From 21a5981905709974f2c60d9e3118945de4a0e23b Mon Sep 17 00:00:00 2001 From: Jan Vidar Krey Date: Thu, 21 Jan 2010 17:26:27 +0100 Subject: [PATCH] Make sure start_listening_socket does everything, this will lead the way to multiple listen ports. --- src/core/hub.c | 54 +++++++++++++++--------------------- src/core/netevent.c | 14 ++-------- src/core/probe.c | 3 +- src/network/connection.h | 3 -- src/network/network.c | 60 ++++++++++++++++++++++++++++++++-------- src/network/network.h | 2 ++ 6 files changed, 75 insertions(+), 61 deletions(-) diff --git a/src/core/hub.c b/src/core/hub.c index 96ffb91..ad72826 100644 --- a/src/core/hub.c +++ b/src/core/hub.c @@ -450,37 +450,28 @@ static void hub_event_dispatcher(void* callback_data, struct event_data* message } } -static int start_listening_socket(const char* bind_addr, uint16_t port, int backlog, char* address_out) +static struct net_connection* start_listening_socket(const char* bind_addr, uint16_t port, int backlog, struct hub_info* hub) { + struct net_connection* server; struct sockaddr_storage addr; socklen_t sockaddr_size; - int af, sd, ret; + int sd, ret; if (ip_convert_address(bind_addr, port, (struct sockaddr*) &addr, &sockaddr_size) == -1) { - return -1; + return 0; } - af = addr.ss_family; - if (af == AF_INET) - { - net_address_to_string(AF_INET, &((struct sockaddr_in*) &addr)->sin_addr, address_out, INET6_ADDRSTRLEN); - } - else if (af == AF_INET6) - { - net_address_to_string(AF_INET6, &((struct sockaddr_in6*) &addr)->sin6_addr, address_out, INET6_ADDRSTRLEN); - } - - sd = net_socket_create(af, SOCK_STREAM, IPPROTO_TCP); + sd = net_socket_create(addr.ss_family, SOCK_STREAM, IPPROTO_TCP); if (sd == -1) { - return -1; + return 0; } if ((net_set_reuseaddress(sd, 1) == -1) || (net_set_nonblocking(sd, 1) == -1)) { net_close(sd); - return -1; + return 0; } ret = net_bind(sd, (struct sockaddr*) &addr, sockaddr_size); @@ -488,7 +479,7 @@ static int start_listening_socket(const char* bind_addr, uint16_t port, int back { LOG_ERROR("hub_start_service(): Unable to bind to TCP local address. errno=%d, str=%s", net_error(), net_error_string(net_error())); net_close(sd); - return -1; + return 0; } ret = net_listen(sd, backlog); @@ -496,16 +487,19 @@ static int start_listening_socket(const char* bind_addr, uint16_t port, int back { LOG_ERROR("hub_start_service(): Unable to listen to socket"); net_close(sd); - return -1; + return 0; } - return sd; + + server = net_con_create(); + net_con_initialize(server, sd, net_on_accept, hub, NET_EVENT_READ); + + return server; } struct hub_info* hub_start_service(struct hub_config* config) { struct hub_info* hub = 0; - int server_tcp, ipv6_supported; - char address_buf[INET6_ADDRSTRLEN+1]; + int ipv6_supported; hub = hub_malloc_zero(sizeof(struct hub_info)); if (!hub) @@ -521,14 +515,14 @@ struct hub_info* hub_start_service(struct hub_config* config) else LOG_DEBUG("IPv6 not supported."); - server_tcp = start_listening_socket(config->server_bind_addr, config->server_port, config->server_listen_backlog, address_buf); - if (server_tcp == -1) + hub->server = start_listening_socket(config->server_bind_addr, config->server_port, config->server_listen_backlog, hub); + if (!hub->server) { hub_free(hub); LOG_FATAL("Unable to start hub service"); return 0; } - LOG_INFO("Starting " PRODUCT "/" VERSION ", listening on %s:%d...", address_buf, config->server_port); + LOG_INFO("Starting " PRODUCT "/" VERSION ", listening on %s:%d...", net_get_local_address(hub->server->sd), config->server_port); #ifdef SSL_SUPPORT if (config->tls_enable) @@ -558,22 +552,21 @@ struct hub_info* hub_start_service(struct hub_config* config) } #endif - hub->config = config; hub->users = NULL; if (uman_init(hub) == -1) { + net_con_close(hub->server); hub_free(hub); - net_close(server_tcp); return 0; } if (event_queue_initialize(&hub->queue, hub_event_dispatcher, (void*) hub) == -1) { + net_con_close(hub->server); uman_shutdown(hub); hub_free(hub); - net_close(server_tcp); return 0; } @@ -581,11 +574,11 @@ struct hub_info* hub_start_service(struct hub_config* config) hub->sendbuf = hub_malloc(MAX_SEND_BUF); if (!hub->recvbuf || !hub->sendbuf) { + net_con_close(hub->server); hub_free(hub->recvbuf); hub_free(hub->sendbuf); uman_shutdown(hub); hub_free(hub); - net_close(server_tcp); return 0; } @@ -593,21 +586,18 @@ struct hub_info* hub_start_service(struct hub_config* config) hub->logout_info = (struct linked_list*) list_create(); if (!hub->chat_history) { + net_con_close(hub->server); list_destroy(hub->chat_history); list_destroy(hub->logout_info); hub_free(hub->recvbuf); hub_free(hub->sendbuf); uman_shutdown(hub); hub_free(hub); - net_close(server_tcp); return 0; } hub->status = hub_status_running; - hub->server = net_con_create(); - net_con_initialize(hub->server, server_tcp, net_on_accept, hub, NET_EVENT_READ); - g_hub = hub; return hub; } diff --git a/src/core/netevent.c b/src/core/netevent.c index f0a2636..0c9fe4d 100644 --- a/src/core/netevent.c +++ b/src/core/netevent.c @@ -165,23 +165,13 @@ void net_event(struct net_connection* con, int event, void *arg) LOG_TRACE("net_event() : fd=%d, ev=%d, arg=%p", fd, (int) event, arg); #endif - if (event == NET_EVENT_SOCKERROR) - { - hub_disconnect_user(g_hub, user, quit_socket_error); - return; - } - else if (event == NET_EVENT_CLOSED) - { - hub_disconnect_user(g_hub, user, quit_disconnected); - return; - } - else if (event == NET_EVENT_TIMEOUT) + if (event == NET_EVENT_TIMEOUT) { if (user_is_connecting(user)) { hub_disconnect_user(g_hub, user, quit_timeout); - return; } + return; } if (event & NET_EVENT_READ) diff --git a/src/core/probe.c b/src/core/probe.c index 547f1e5..8a480de 100644 --- a/src/core/probe.c +++ b/src/core/probe.c @@ -26,8 +26,7 @@ static char probe_recvbuf[PROBE_RECV_SIZE]; static void probe_net_event(struct net_connection* con, int events, void *arg) { struct hub_probe* probe = (struct hub_probe*) net_con_get_ptr(con); - - if (events == NET_EVENT_SOCKERROR || events == NET_EVENT_CLOSED || events == NET_EVENT_TIMEOUT) + if (events == NET_EVENT_TIMEOUT) { probe_destroy(probe); return; diff --git a/src/network/connection.h b/src/network/connection.h index 06fcc70..ea15d35 100644 --- a/src/network/connection.h +++ b/src/network/connection.h @@ -27,8 +27,6 @@ #define NET_EVENT_TIMEOUT 0x0001 #define NET_EVENT_READ 0x0002 #define NET_EVENT_WRITE 0x0004 -#define NET_EVENT_SOCKERROR 0x1000 /* Socket error, closed */ -#define NET_EVENT_CLOSED 0x2000 /* Socket closed */ struct net_connection; @@ -53,7 +51,6 @@ extern void net_con_callback(struct net_connection* con, int events); * Close the connection. * This will ensure a connection is closed properly and will generate a NET_EVENT_DESTROYED event which indicates * that the con can safely be deleted (or set to NULL). - * @returns 1 if the memory pointed to by con can be freed immediately, or 0 if it needs to go through the NET_EVENT_DESTROYED event. */ extern void net_con_close(struct net_connection* con); diff --git a/src/network/network.c b/src/network/network.c index a4dba1b..431c8a5 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -381,11 +381,11 @@ int net_accept(int fd, struct ip_addr_encap* ipaddr) { char address[INET6_ADDRSTRLEN+1] = { 0, }; net_address_to_string(AF_INET6, (void*) &addr6->sin6_addr, address, INET6_ADDRSTRLEN+1); - if (!strncmp(address, "::ffff:", 7)) + if (strchr(address, '.')) { /* Hack to convert IPv6 mapped IPv4 addresses to true IPv4 addresses */ - net_string_to_address(AF_INET, address + 7, (void*) &ipaddr->internal_ip_data.in); ipaddr->af = AF_INET; + net_string_to_address(AF_INET, address, (void*) &ipaddr->internal_ip_data.in); } else { @@ -526,7 +526,12 @@ const char* net_address_to_string(int af, const void* src, char* dst, socklen_t return NULL; #else - return inet_ntop(af, src, dst, cnt); + const char* address = inet_ntop(af, src, dst, cnt); + if (af == AF_INET6 && strncmp(address, "::ffff:", 7) == 0) /* IPv6 mapped IPv4 address. */ + { + return &address[7]; + } + return address; #endif } @@ -573,9 +578,6 @@ int net_string_to_address(int af, const char* src, void* dst) #endif } - - - const char* net_get_peer_address(int fd) { static char address[INET6_ADDRSTRLEN+1]; @@ -598,17 +600,12 @@ const char* net_get_peer_address(int fd) if (af == AF_INET6) { net_address_to_string(af, (void*) &name6->sin6_addr, address, INET6_ADDRSTRLEN); - if (strncmp(address, "::ffff:", 7) == 0) /* IPv6 mapped IPv4 address. */ - { - return &address[7]; - } - return address; } else { net_address_to_string(af, (void*) &name4->sin_addr, address, INET6_ADDRSTRLEN); - return address; } + return address; } else { @@ -619,6 +616,45 @@ const char* net_get_peer_address(int fd) return "0.0.0.0"; } +const char* net_get_local_address(int fd) +{ + static char address[INET6_ADDRSTRLEN+1]; + struct sockaddr_storage storage; + struct sockaddr_in6* name6; + struct sockaddr_in* name4; + struct sockaddr* name; + + memset(address, 0, INET6_ADDRSTRLEN); + socklen_t namelen = sizeof(struct sockaddr_storage); + memset(&storage, 0, namelen); + + name6 = (struct sockaddr_in6*) &storage; + name4 = (struct sockaddr_in*) &storage; + name = (struct sockaddr*) &storage; + + if (getsockname(fd, (struct sockaddr*) name, &namelen) != -1) + { + int af = name4->sin_family; + if (af == AF_INET6) + { + net_address_to_string(af, (void*) &name6->sin6_addr, address, INET6_ADDRSTRLEN); + } + else + { + net_address_to_string(af, (void*) &name4->sin_addr, address, INET6_ADDRSTRLEN); + } + return address; + } + else + { + net_error_out(fd, "net_get_local_address"); + net_stats_add_error(); + } + + return "0.0.0.0"; +} + + ssize_t net_recv(int fd, void* buf, size_t len, int flags) { diff --git a/src/network/network.h b/src/network/network.h index c4ee234..c1a1066 100644 --- a/src/network/network.h +++ b/src/network/network.h @@ -224,6 +224,8 @@ extern int net_is_ipv6_supported(); */ extern const char* net_get_peer_address(int fd); +extern const char* net_get_local_address(int fd); + /** * See man(3) inet_ntop. */