diff --git a/src/apps/peer/mainudpserver.c b/src/apps/peer/mainudpserver.c index c8ef9f3aa..654e3adc9 100644 --- a/src/apps/peer/mainudpserver.c +++ b/src/apps/peer/mainudpserver.c @@ -58,7 +58,7 @@ int main(int argc, char **argv) { char **local_addr_list = NULL; size_t las = 0; int verbose = TURN_VERBOSE_NONE; - int c; + int c = 0; char ifname[1025] = "\0"; if (socket_init()) @@ -87,7 +87,7 @@ int main(int argc, char **argv) { break; default: fprintf(stderr, "%s\n", Usage); - exit(1); + return -2; } if (las < 1) { @@ -98,6 +98,8 @@ int main(int argc, char **argv) { } server_type *server = start_udp_server(verbose, ifname, local_addr_list, las, port); + if (!server) + return -3; run_udp_server(server); clean_udp_server(server); diff --git a/src/apps/peer/udpserver.c b/src/apps/peer/udpserver.c index bcc5b5691..d1bab350d 100644 --- a/src/apps/peer/udpserver.c +++ b/src/apps/peer/udpserver.c @@ -32,6 +32,13 @@ #include "apputils.h" #include "stun_buffer.h" +struct listen_info { + ioa_addr addr; + int received; + int verbose; + struct listen_info *next; +}; + /////////////// io handlers /////////////////// static void udp_server_input_handler(evutil_socket_t fd, short what, void *arg) { @@ -39,71 +46,96 @@ static void udp_server_input_handler(evutil_socket_t fd, short what, void *arg) if (!(what & EV_READ)) return; - ioa_addr *addr = (ioa_addr *)arg; + struct listen_info *listen = (struct listen_info *)arg; int len = 0; - int slen = get_ioa_addr_len(addr); - stun_buffer buffer; - ioa_addr remote_addr; + int slen = get_ioa_addr_len(&listen->addr); + stun_buffer *buffer = (stun_buffer *)malloc(sizeof(stun_buffer)); + ioa_addr remote_addr = {0}; + if (!buffer) + return; do { - len = recvfrom(fd, buffer.buf, sizeof(buffer.buf) - 1, 0, (struct sockaddr *)&remote_addr, (socklen_t *)&slen); + len = recvfrom(fd, buffer->buf, sizeof(buffer->buf) - 1, 0, (struct sockaddr *)&remote_addr, (socklen_t *)&slen); } while (len < 0 && socket_eintr()); - buffer.len = len; + buffer->len = len; if (len >= 0) { + listen->received += len; + if (listen->verbose) { + uint8_t ra[64], la[64]; + addr_to_string(&listen->addr, la); + addr_to_string(&remote_addr, ra); + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "Received %d bytes data %s from %s. total received: %d bytes\n", len, la, ra, listen->received); + } + do { - len = sendto(fd, buffer.buf, buffer.len, 0, (const struct sockaddr *)&remote_addr, (socklen_t)slen); + len = sendto(fd, buffer->buf, buffer->len, 0, (const struct sockaddr *)&remote_addr, (socklen_t)slen); } while (len < 0 && (socket_eintr() || socket_enobufs() || socket_eagain())); } + + free(buffer); } ///////////////////// operations ////////////////////////// -static int udp_create_server_socket(server_type *server, const char *ifname, const char *local_address, int port) { - - if (server && server->verbose) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Start\n"); +static struct listen_info *udp_create_server_socket(server_type *server, const char *ifname, const char *local_address, + int port) { + if (!server) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "server is null\n"); + return NULL; + } - if (!server) - return -1; + struct listen_info *listen = (struct listen_info *)calloc(sizeof(struct listen_info), 1); + if (!listen) + return NULL; - evutil_socket_t udp_fd = -1; - ioa_addr *server_addr = (ioa_addr *)malloc(sizeof(ioa_addr)); + do { + evutil_socket_t udp_fd = -1; + listen->verbose = server->verbose; + ioa_addr *server_addr = &listen->addr; - STRCPY(server->ifname, ifname); + STRCPY(server->ifname, ifname); - if (make_ioa_addr((const uint8_t *)local_address, port, server_addr) < 0) - return -1; + if (make_ioa_addr((const uint8_t *)local_address, port, server_addr) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "make_ioa_addr fail %s:%d\n", local_address, port); + break; + } - udp_fd = socket(server_addr->ss.sa_family, RELAY_DGRAM_SOCKET_TYPE, RELAY_DGRAM_SOCKET_PROTOCOL); - if (udp_fd < 0) { - perror("socket"); - free(server_addr); - return -1; - } + udp_fd = socket(server_addr->ss.sa_family, RELAY_DGRAM_SOCKET_TYPE, RELAY_DGRAM_SOCKET_PROTOCOL); + if (udp_fd < 0) { + perror("socket"); + break; + } - if (sock_bind_to_device(udp_fd, (unsigned char *)server->ifname) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot bind udp server socket to device %s\n", server->ifname); - } + if (sock_bind_to_device(udp_fd, (unsigned char *)server->ifname) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot bind udp server socket to device %s\n", server->ifname); + break; + } - set_sock_buf_size(udp_fd, UR_SERVER_SOCK_BUF_SIZE); + set_sock_buf_size(udp_fd, UR_SERVER_SOCK_BUF_SIZE); - if (addr_bind(udp_fd, server_addr, 1, 1, UDP_SOCKET) < 0) - return -1; + if (addr_bind(udp_fd, server_addr, 1, 1, UDP_SOCKET) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot bind udp server socket to %s:%d\n", local_address, port); + break; + } - socket_set_nonblocking(udp_fd); + socket_set_nonblocking(udp_fd); - struct event *udp_ev = - event_new(server->event_base, udp_fd, EV_READ | EV_PERSIST, udp_server_input_handler, server_addr); + struct event *udp_ev = + event_new(server->event_base, udp_fd, EV_READ | EV_PERSIST, udp_server_input_handler, listen); + if (udp_ev) + event_add(udp_ev, NULL); - event_add(udp_ev, NULL); + if (server && server->verbose) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s:%d start\n", local_address, port); - if (server && server->verbose) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "End\n"); + return listen; + } while (0); - return 0; + free(listen); + return NULL; } static server_type *init_server(int verbose, const char *ifname, char **local_addresses, size_t las, int port) { @@ -111,7 +143,7 @@ static server_type *init_server(int verbose, const char *ifname, char **local_ad server_type *server = (server_type *)malloc(sizeof(server_type)); if (!server) - return server; + return NULL; memset(server, 0, sizeof(server_type)); @@ -120,8 +152,17 @@ static server_type *init_server(int verbose, const char *ifname, char **local_ad server->event_base = turn_event_base_new(); while (las) { - udp_create_server_socket(server, ifname, local_addresses[--las], port); - udp_create_server_socket(server, ifname, local_addresses[las], port + 1); + struct listen_info *listen = NULL; + listen = udp_create_server_socket(server, ifname, local_addresses[--las], port); + if (listen) { + listen->next = server->listen; + server->listen = listen; + } + listen = udp_create_server_socket(server, ifname, local_addresses[las], port + 1); + if (listen) { + listen->next = server->listen; + server->listen = listen; + } } return server; @@ -131,6 +172,14 @@ static int clean_server(server_type *server) { if (server) { if (server->event_base) event_base_free(server->event_base); + + struct listen_info *l = server->listen; + while (l) { + struct listen_info *n = l->next; + free(l); + l = n; + } + free(server); } return 0; diff --git a/src/apps/peer/udpserver.h b/src/apps/peer/udpserver.h index 3ff1d861b..dc56ed046 100644 --- a/src/apps/peer/udpserver.h +++ b/src/apps/peer/udpserver.h @@ -45,13 +45,14 @@ extern "C" { struct server_info; typedef struct server_info server_type; - +typedef struct listen_info listen_type; /////////////////////////////////////////////////////// struct server_info { char ifname[1025]; struct event_base *event_base; int verbose; + listen_type *listen; }; //////////////////////////////