Make sure start_listening_socket does everything, this will lead the way to multiple listen ports.
This commit is contained in:
parent
c47ea14047
commit
21a5981905
@ -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;
|
struct sockaddr_storage addr;
|
||||||
socklen_t sockaddr_size;
|
socklen_t sockaddr_size;
|
||||||
int af, sd, ret;
|
int sd, ret;
|
||||||
|
|
||||||
if (ip_convert_address(bind_addr, port, (struct sockaddr*) &addr, &sockaddr_size) == -1)
|
if (ip_convert_address(bind_addr, port, (struct sockaddr*) &addr, &sockaddr_size) == -1)
|
||||||
{
|
{
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
af = addr.ss_family;
|
sd = net_socket_create(addr.ss_family, SOCK_STREAM, IPPROTO_TCP);
|
||||||
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);
|
|
||||||
if (sd == -1)
|
if (sd == -1)
|
||||||
{
|
{
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((net_set_reuseaddress(sd, 1) == -1) || (net_set_nonblocking(sd, 1) == -1))
|
if ((net_set_reuseaddress(sd, 1) == -1) || (net_set_nonblocking(sd, 1) == -1))
|
||||||
{
|
{
|
||||||
net_close(sd);
|
net_close(sd);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = net_bind(sd, (struct sockaddr*) &addr, sockaddr_size);
|
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()));
|
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);
|
net_close(sd);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = net_listen(sd, backlog);
|
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");
|
LOG_ERROR("hub_start_service(): Unable to listen to socket");
|
||||||
net_close(sd);
|
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_start_service(struct hub_config* config)
|
||||||
{
|
{
|
||||||
struct hub_info* hub = 0;
|
struct hub_info* hub = 0;
|
||||||
int server_tcp, ipv6_supported;
|
int ipv6_supported;
|
||||||
char address_buf[INET6_ADDRSTRLEN+1];
|
|
||||||
|
|
||||||
hub = hub_malloc_zero(sizeof(struct hub_info));
|
hub = hub_malloc_zero(sizeof(struct hub_info));
|
||||||
if (!hub)
|
if (!hub)
|
||||||
@ -521,14 +515,14 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
|||||||
else
|
else
|
||||||
LOG_DEBUG("IPv6 not supported.");
|
LOG_DEBUG("IPv6 not supported.");
|
||||||
|
|
||||||
server_tcp = start_listening_socket(config->server_bind_addr, config->server_port, config->server_listen_backlog, address_buf);
|
hub->server = start_listening_socket(config->server_bind_addr, config->server_port, config->server_listen_backlog, hub);
|
||||||
if (server_tcp == -1)
|
if (!hub->server)
|
||||||
{
|
{
|
||||||
hub_free(hub);
|
hub_free(hub);
|
||||||
LOG_FATAL("Unable to start hub service");
|
LOG_FATAL("Unable to start hub service");
|
||||||
return 0;
|
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
|
#ifdef SSL_SUPPORT
|
||||||
if (config->tls_enable)
|
if (config->tls_enable)
|
||||||
@ -558,22 +552,21 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
hub->config = config;
|
hub->config = config;
|
||||||
hub->users = NULL;
|
hub->users = NULL;
|
||||||
|
|
||||||
if (uman_init(hub) == -1)
|
if (uman_init(hub) == -1)
|
||||||
{
|
{
|
||||||
|
net_con_close(hub->server);
|
||||||
hub_free(hub);
|
hub_free(hub);
|
||||||
net_close(server_tcp);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event_queue_initialize(&hub->queue, hub_event_dispatcher, (void*) hub) == -1)
|
if (event_queue_initialize(&hub->queue, hub_event_dispatcher, (void*) hub) == -1)
|
||||||
{
|
{
|
||||||
|
net_con_close(hub->server);
|
||||||
uman_shutdown(hub);
|
uman_shutdown(hub);
|
||||||
hub_free(hub);
|
hub_free(hub);
|
||||||
net_close(server_tcp);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,11 +574,11 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
|||||||
hub->sendbuf = hub_malloc(MAX_SEND_BUF);
|
hub->sendbuf = hub_malloc(MAX_SEND_BUF);
|
||||||
if (!hub->recvbuf || !hub->sendbuf)
|
if (!hub->recvbuf || !hub->sendbuf)
|
||||||
{
|
{
|
||||||
|
net_con_close(hub->server);
|
||||||
hub_free(hub->recvbuf);
|
hub_free(hub->recvbuf);
|
||||||
hub_free(hub->sendbuf);
|
hub_free(hub->sendbuf);
|
||||||
uman_shutdown(hub);
|
uman_shutdown(hub);
|
||||||
hub_free(hub);
|
hub_free(hub);
|
||||||
net_close(server_tcp);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -593,21 +586,18 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
|||||||
hub->logout_info = (struct linked_list*) list_create();
|
hub->logout_info = (struct linked_list*) list_create();
|
||||||
if (!hub->chat_history)
|
if (!hub->chat_history)
|
||||||
{
|
{
|
||||||
|
net_con_close(hub->server);
|
||||||
list_destroy(hub->chat_history);
|
list_destroy(hub->chat_history);
|
||||||
list_destroy(hub->logout_info);
|
list_destroy(hub->logout_info);
|
||||||
hub_free(hub->recvbuf);
|
hub_free(hub->recvbuf);
|
||||||
hub_free(hub->sendbuf);
|
hub_free(hub->sendbuf);
|
||||||
uman_shutdown(hub);
|
uman_shutdown(hub);
|
||||||
hub_free(hub);
|
hub_free(hub);
|
||||||
net_close(server_tcp);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hub->status = hub_status_running;
|
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;
|
g_hub = hub;
|
||||||
return hub;
|
return hub;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
LOG_TRACE("net_event() : fd=%d, ev=%d, arg=%p", fd, (int) event, arg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (event == NET_EVENT_SOCKERROR)
|
if (event == NET_EVENT_TIMEOUT)
|
||||||
{
|
|
||||||
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 (user_is_connecting(user))
|
if (user_is_connecting(user))
|
||||||
{
|
{
|
||||||
hub_disconnect_user(g_hub, user, quit_timeout);
|
hub_disconnect_user(g_hub, user, quit_timeout);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event & NET_EVENT_READ)
|
if (event & NET_EVENT_READ)
|
||||||
|
@ -26,8 +26,7 @@ static char probe_recvbuf[PROBE_RECV_SIZE];
|
|||||||
static void probe_net_event(struct net_connection* con, int events, void *arg)
|
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);
|
struct hub_probe* probe = (struct hub_probe*) net_con_get_ptr(con);
|
||||||
|
if (events == NET_EVENT_TIMEOUT)
|
||||||
if (events == NET_EVENT_SOCKERROR || events == NET_EVENT_CLOSED || events == NET_EVENT_TIMEOUT)
|
|
||||||
{
|
{
|
||||||
probe_destroy(probe);
|
probe_destroy(probe);
|
||||||
return;
|
return;
|
||||||
|
@ -27,8 +27,6 @@
|
|||||||
#define NET_EVENT_TIMEOUT 0x0001
|
#define NET_EVENT_TIMEOUT 0x0001
|
||||||
#define NET_EVENT_READ 0x0002
|
#define NET_EVENT_READ 0x0002
|
||||||
#define NET_EVENT_WRITE 0x0004
|
#define NET_EVENT_WRITE 0x0004
|
||||||
#define NET_EVENT_SOCKERROR 0x1000 /* Socket error, closed */
|
|
||||||
#define NET_EVENT_CLOSED 0x2000 /* Socket closed */
|
|
||||||
|
|
||||||
struct net_connection;
|
struct net_connection;
|
||||||
|
|
||||||
@ -53,7 +51,6 @@ extern void net_con_callback(struct net_connection* con, int events);
|
|||||||
* Close the connection.
|
* Close the connection.
|
||||||
* This will ensure a connection is closed properly and will generate a NET_EVENT_DESTROYED event which indicates
|
* 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).
|
* 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);
|
extern void net_con_close(struct net_connection* con);
|
||||||
|
|
||||||
|
@ -381,11 +381,11 @@ int net_accept(int fd, struct ip_addr_encap* ipaddr)
|
|||||||
{
|
{
|
||||||
char address[INET6_ADDRSTRLEN+1] = { 0, };
|
char address[INET6_ADDRSTRLEN+1] = { 0, };
|
||||||
net_address_to_string(AF_INET6, (void*) &addr6->sin6_addr, address, INET6_ADDRSTRLEN+1);
|
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 */
|
/* 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;
|
ipaddr->af = AF_INET;
|
||||||
|
net_string_to_address(AF_INET, address, (void*) &ipaddr->internal_ip_data.in);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -526,7 +526,12 @@ const char* net_address_to_string(int af, const void* src, char* dst, socklen_t
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
#else
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,9 +578,6 @@ int net_string_to_address(int af, const char* src, void* dst)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char* net_get_peer_address(int fd)
|
const char* net_get_peer_address(int fd)
|
||||||
{
|
{
|
||||||
static char address[INET6_ADDRSTRLEN+1];
|
static char address[INET6_ADDRSTRLEN+1];
|
||||||
@ -598,17 +600,12 @@ const char* net_get_peer_address(int fd)
|
|||||||
if (af == AF_INET6)
|
if (af == AF_INET6)
|
||||||
{
|
{
|
||||||
net_address_to_string(af, (void*) &name6->sin6_addr, address, INET6_ADDRSTRLEN);
|
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
|
else
|
||||||
{
|
{
|
||||||
net_address_to_string(af, (void*) &name4->sin_addr, address, INET6_ADDRSTRLEN);
|
net_address_to_string(af, (void*) &name4->sin_addr, address, INET6_ADDRSTRLEN);
|
||||||
return address;
|
|
||||||
}
|
}
|
||||||
|
return address;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -619,6 +616,45 @@ const char* net_get_peer_address(int fd)
|
|||||||
return "0.0.0.0";
|
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)
|
ssize_t net_recv(int fd, void* buf, size_t len, int flags)
|
||||||
{
|
{
|
||||||
|
@ -224,6 +224,8 @@ extern int net_is_ipv6_supported();
|
|||||||
*/
|
*/
|
||||||
extern const char* net_get_peer_address(int fd);
|
extern const char* net_get_peer_address(int fd);
|
||||||
|
|
||||||
|
extern const char* net_get_local_address(int fd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See man(3) inet_ntop.
|
* See man(3) inet_ntop.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user