From: Enlightenment S. <no-...@en...> - 2008-10-06 09:30:56
|
Log: Add full UDP client/server support. Patch from Matt Barclay. Author: cedric Date: 2008-10-06 02:28:15 -0700 (Mon, 06 Oct 2008) New Revision: 36474 Modified: trunk/TEST/orig/ecore/Makefile trunk/TEST/orig/ecore/con_client_udp_example.c trunk/TEST/orig/ecore/con_mcast_example.c trunk/ecore/AUTHORS trunk/ecore/src/lib/ecore_con/ecore_con.c Modified: trunk/TEST/orig/ecore/Makefile =================================================================== --- trunk/TEST/orig/ecore/Makefile 2008-10-06 07:22:18 UTC (rev 36473) +++ trunk/TEST/orig/ecore/Makefile 2008-10-06 09:28:15 UTC (rev 36474) @@ -1,7 +1,7 @@ FLAGS = `pkg-config ecore ecore-evas ecore-job ecore-config ecore-x evas --cflags` LIBS = `pkg-config ecore ecore-evas ecore-job ecore-config ecore-x evas --libs` -BINS = ecore_config ecore_evas_test ecore_test +BINS = ecore_config ecore_evas_test ecore_test con_client_udp_example con_mcast_example con_server_udp_example all: $(BINS) ecore_config_SRCS = ecore_config.c @@ -40,6 +40,24 @@ $(RM) $@ $(CC) $(LIBS) $(LDFLAGS) $(ecore_dbus_receiver_test_OBJS) -o $@ +con_client_udp_example_SRCS = con_client_udp_example.c +con_client_udp_example_OBJS = $(con_client_udp_example_SRCS:.c=.o) +con_client_udp_example: $(con_client_udp_example_OBJS) + $(RM) $@ + $(CC) $(LIBS) $(LDFLAGS) $(con_client_udp_example_OBJS) -o $@ + +con_mcast_example_SRCS = con_mcast_example.c +con_mcast_example_OBJS = $(con_mcast_example_SRCS:.c=.o) +con_mcast_example: $(con_mcast_example_OBJS) + $(RM) $@ + $(CC) $(LIBS) $(LDFLAGS) $(con_mcast_example_OBJS) -o $@ + +con_server_udp_example_SRCS = con_server_udp_example.c +con_server_udp_example_OBJS = $(con_server_udp_example_SRCS:.c=.o) +con_server_udp_example: $(con_server_udp_example_OBJS) + $(RM) $@ + $(CC) $(LIBS) $(LDFLAGS) $(con_server_udp_example_OBJS) -o $@ + ############################################################################ #### boilerplate .c.o: Modified: trunk/TEST/orig/ecore/con_client_udp_example.c =================================================================== --- trunk/TEST/orig/ecore/con_client_udp_example.c 2008-10-06 07:22:18 UTC (rev 36473) +++ trunk/TEST/orig/ecore/con_client_udp_example.c 2008-10-06 09:28:15 UTC (rev 36474) @@ -9,11 +9,12 @@ #include <string.h> Ecore_Con_Server *svr; +Ecore_Con_Server *mcast; #define SOCKET_NAME "con_example" #define SOCKET_PORT 0 -char *msg = "get http://www.enlightenment.org\n"; +char *msg = "EFL UDP CLIENT"; typedef int (*Handler_Func) (void *data, int type, void *event); @@ -22,7 +23,7 @@ int ev_type, Ecore_Con_Event_Server_Data *ev) { printf("Data received from the server! Data was:\n"); - printf("%d, %s \n", ev->size, (char *)ev->data); + printf("%d, %s \n", ev->size, ev->data); ecore_con_server_send(svr, ev->data, ev->size); @@ -35,19 +36,28 @@ ecore_con_init(); // Try to conect to server. - svr = ecore_con_server_connect(ECORE_CON_REMOTE_UDP, "239.255.2.1", - 6767, NULL); + svr = ecore_con_server_connect(ECORE_CON_REMOTE_UDP, "127.0.0.1",6767, NULL); if (NULL == svr) { printf("*** This really shouldn't happen. Bad port? DNS lookup couldn't fork? \n"); return 0; } printf("Sending Datagrams to localhost:6767 \n"); + // Try to conect to server. + mcast = ecore_con_server_connect(ECORE_CON_REMOTE_UDP, "239.255.2.1", 1199, NULL); + if (NULL == svr) { + printf("*** This really shouldn't happen. Bad port? DNS lookup couldn't fork? \n"); + return 0; + } + printf("Sending Datagrams to 239.255.2.1:1199 \n"); + ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, (Handler_Func)server_data, NULL); ecore_con_server_send(svr, msg, strlen(msg)); + ecore_con_server_send(mcast, msg, strlen(msg)); + ecore_main_loop_begin(); ecore_con_server_del(svr); Modified: trunk/TEST/orig/ecore/con_mcast_example.c =================================================================== --- trunk/TEST/orig/ecore/con_mcast_example.c 2008-10-06 07:22:18 UTC (rev 36473) +++ trunk/TEST/orig/ecore/con_mcast_example.c 2008-10-06 09:28:15 UTC (rev 36474) @@ -12,6 +12,10 @@ typedef int (*Handler_Func) (void *data, int type, void *event); +/* +Please note that ev->client->data points to a sockaddr_in stucture. If you overwrite that pointer +your program will have a memory leak +*/ int client_data (void *data, int ev_type, @@ -38,7 +42,7 @@ svr = ecore_con_server_add(ECORE_CON_REMOTE_MCAST, "239.255.2.1", 1199, NULL); if( NULL == svr ) { - printf("Unable to add server\n"); + printf("Unable to add server. Bad port? No route to the multicast network?\n"); return 1; } else Modified: trunk/ecore/AUTHORS =================================================================== --- trunk/ecore/AUTHORS 2008-10-06 07:22:18 UTC (rev 36473) +++ trunk/ecore/AUTHORS 2008-10-06 09:28:15 UTC (rev 36474) @@ -21,3 +21,4 @@ Brian 'rephorm' Mattern <re...@re...> Tim Horton <hor...@gm...> Arnaud de Turckheim 'quarium' <qu...@gm...> +Matt Barclay <mba...@gm...> Modified: trunk/ecore/src/lib/ecore_con/ecore_con.c =================================================================== --- trunk/ecore/src/lib/ecore_con/ecore_con.c 2008-10-06 07:22:18 UTC (rev 36473) +++ trunk/ecore/src/lib/ecore_con/ecore_con.c 2008-10-06 09:28:15 UTC (rev 36474) @@ -33,7 +33,7 @@ static int _ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler); static int _ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler); static int _ecore_con_cl_udp_handler(void *data, Ecore_Fd_Handler *fd_handler); -static int _ecore_con_mcast_handler(void *data, Ecore_Fd_Handler *fd_handler); +static int _ecore_con_svr_udp_handler(void *data, Ecore_Fd_Handler *fd_handler); static int _ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler); static void _ecore_con_server_flush(Ecore_Con_Server *svr); static void _ecore_con_client_flush(Ecore_Con_Client *cl); @@ -298,7 +298,7 @@ umask(pmode); goto error; } - svr->fd_handler = + svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ, _ecore_con_svr_handler, svr, NULL, NULL); umask(pmode); @@ -323,23 +323,31 @@ _ecore_con_svr_handler, svr, NULL, NULL); if (!svr->fd_handler) goto error; } - else if (type == ECORE_CON_REMOTE_MCAST) + else if (type == ECORE_CON_REMOTE_MCAST || type == ECORE_CON_REMOTE_UDP) { svr->fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if(svr->fd < 0) goto error; - mreq.imr_multiaddr.s_addr = inet_addr(name); - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,sizeof(mreq)) != 0) goto error; + + socket_addr.sin_family = AF_INET; + socket_addr.sin_port = htons(port); + + if (type == ECORE_CON_REMOTE_MCAST) + { + socket_addr.sin_addr.s_addr = inet_addr(name); + mreq.imr_multiaddr.s_addr = inet_addr(name); + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,sizeof(mreq)) != 0) goto error; + } + else + socket_addr.sin_addr.s_addr = htonl(INADDR_ANY); + if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &on,sizeof(on)) != 0) goto error; if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error; if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error; - socket_addr.sin_family = AF_INET; - socket_addr.sin_port = htons(port); - socket_addr.sin_addr.s_addr = inet_addr(name); if (bind(svr->fd, (struct sockaddr *)&socket_addr,sizeof(struct sockaddr_in)) < 0) goto error; svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ, - _ecore_con_mcast_handler, svr, NULL, NULL); + _ecore_con_svr_udp_handler, svr, NULL, NULL); if (!svr->fd_handler) goto error; } @@ -806,15 +814,20 @@ if (size < 1) return 0; if (cl->fd_handler) ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE); - if (cl->buf) + + if(cl->server && cl->server->type == ECORE_CON_REMOTE_UDP) { - unsigned char *newbuf; + sendto(cl->server->fd, data, size, 0, (struct sockaddr *) cl->data, sizeof(struct sockaddr_in)); + } + else if (cl->buf) + { + unsigned char *newbuf; - newbuf = realloc(cl->buf, cl->buf_size + size); - if (newbuf) cl->buf = newbuf; - else return 0; - memcpy(cl->buf + cl->buf_size, data, size); - cl->buf_size += size; + newbuf = realloc(cl->buf, cl->buf_size + size); + if (newbuf) cl->buf = newbuf; + else return 0; + memcpy(cl->buf + cl->buf_size, data, size); + cl->buf_size += size; } else { @@ -853,14 +866,20 @@ EAPI void * ecore_con_client_del(Ecore_Con_Client *cl) { - void *data; + void *data = NULL; if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) { ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_del"); return NULL; } - data = cl->data; + + if(cl->data && cl->server && (cl->server->type == ECORE_CON_REMOTE_UDP || + cl->server->type == ECORE_CON_REMOTE_MCAST)) + free(cl->data); + else + data = cl->data; + cl->data = NULL; cl->delete_me = 1; if (cl->event_count > 0) @@ -1076,7 +1095,7 @@ fcntl(new_fd, F_SETFD, FD_CLOEXEC); cl->fd = new_fd; cl->server = svr; - cl->fd_handler = + cl->fd_handler = ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ, _ecore_con_svr_cl_handler, cl, NULL, NULL); ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT); @@ -1180,7 +1199,7 @@ if (svr->fd < 0) goto error; if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error; if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error; - if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) + if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) goto error; socket_addr.sin_family = AF_INET; socket_addr.sin_port = htons(svr->port); @@ -1191,12 +1210,12 @@ if (errno != EINPROGRESS) goto error; svr->connecting = 1; - svr->fd_handler = + svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE, _ecore_con_cl_handler, svr, NULL, NULL); } else - svr->fd_handler = + svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ, _ecore_con_cl_handler, svr, NULL, NULL); @@ -1265,7 +1284,7 @@ if (svr->fd < 0) goto error; if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error; if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error; - if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) + if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) goto error; socket_addr.sin_family = AF_INET; socket_addr.sin_port = htons(svr->port); @@ -1274,7 +1293,7 @@ if (connect(svr->fd, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr_in)) < 0) goto error; else - svr->fd_handler = + svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE, _ecore_con_cl_udp_handler, svr, NULL, NULL); @@ -1504,7 +1523,7 @@ { unsigned char buf[65536]; int num = 0; - + errno = 0; num = read(svr->fd, buf, 65536); if (num > 0) @@ -1535,41 +1554,78 @@ } else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) _ecore_con_server_flush(svr); - + return 1; } static int -_ecore_con_mcast_handler(void *data, Ecore_Fd_Handler *fd_handler) +_ecore_con_svr_udp_handler(void *data, Ecore_Fd_Handler *fd_handler) { - Ecore_Con_Client *cl; + Ecore_Con_Server *svr; + Ecore_Con_Client *cl; - cl = data; - if (cl->dead) return 1; - if (cl->delete_me) return 1; + svr = data; + if (svr->dead) return 1; + if (svr->delete_me) return 1; if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) { - unsigned char buf[65536]; - int num; + unsigned char buf[READBUFSIZ]; + struct sockaddr_in client_addr; + int num, client_addr_len = sizeof(client_addr); errno = 0; - num = read(cl->fd, buf, 65536); + num = recvfrom(svr->fd, buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr*) &client_addr, &client_addr_len); + if (num > 0) { - if (!cl->delete_me) + if (!svr->delete_me) { Ecore_Con_Event_Client_Data *e; unsigned char *inbuf; + uint32_t ip; + char ipbuf[64]; + /* Create a new client for use in the client data event */ + cl = calloc(1, sizeof(Ecore_Con_Client)); + if(cl == NULL) + return 1; + cl->buf = NULL; + cl->fd = 0; + cl->fd_handler = NULL; + cl->server = svr; + cl->data = calloc(1, sizeof(client_addr)); + if(cl->data == NULL) + { + free(cl); + return 1; + } + memcpy(cl->data, &client_addr, sizeof(client_addr)); + ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT); + ecore_list_append(svr->clients, cl); + + ip = client_addr.sin_addr.s_addr; + snprintf(ipbuf, sizeof(ipbuf), + "%i.%i.%i.%i", + (ip ) & 0xff, + (ip >> 8 ) & 0xff, + (ip >> 16) & 0xff, + (ip >> 24) & 0xff); + cl->ip = strdup(ipbuf); + inbuf = malloc(num); if(inbuf == NULL) - return 1; + { + free(cl->data); + free(cl); + return 1; + } + memcpy(inbuf, buf, num); - + e = calloc(1, sizeof(Ecore_Con_Event_Client_Data)); if (e) { - cl->event_count++; + svr->event_count++; e->client = cl; e->data = inbuf; e->size = num; @@ -1577,30 +1633,44 @@ _ecore_con_event_client_data_free, NULL); } + + if(!cl->delete_me) + { + Ecore_Con_Event_Client_Add *add; + + add = calloc(1, sizeof(Ecore_Con_Event_Client_Add)); + if(add) + { + /*cl->event_count++;*/ + add->client = cl; + ecore_event_add(ECORE_CON_EVENT_CLIENT_ADD, add, + _ecore_con_event_client_add_free, NULL); + } + } } if ((errno == EIO) || (errno == EBADF) || (errno == EPIPE) || (errno == EINVAL) || (errno == ENOSPC) || (num == 0)/* is num == 0 right? */) { - if (!cl->delete_me) + if (!svr->delete_me) { /* we lost our client! */ Ecore_Con_Event_Client_Del *e; - + e = calloc(1, sizeof(Ecore_Con_Event_Client_Del)); if (e) { - cl->event_count++; + svr->event_count++; e->client = cl; ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e, _ecore_con_event_client_del_free, NULL); } } - cl->dead = 1; - if (cl->fd_handler) - ecore_main_fd_handler_del(cl->fd_handler); - cl->fd_handler = NULL; + svr->dead = 1; + if (svr->fd_handler) + ecore_main_fd_handler_del(svr->fd_handler); + svr->fd_handler = NULL; } } } @@ -1842,7 +1912,9 @@ e = ev; e->client->event_count--; if (e->data) free(e->data); - if ((e->client->event_count == 0) && (e->client->delete_me)) + if ((e->client->event_count == 0) && (e->client->delete_me) || + (e->client->server && (e->client->server->type == ECORE_CON_REMOTE_UDP || + e->client->server->type == ECORE_CON_REMOTE_MCAST))) ecore_con_client_del(e->client); free(e); } |