int net_string_to_address(int af, const char* src, void* dst) { #ifdef WINSOCK int ret, size; struct sockaddr_in addr4; struct sockaddr_in6 addr6; struct sockaddr* addr = 0; if (af == AF_INET6) { if (net_is_ipv6_supported() != 1) return -1; size = sizeof(struct sockaddr_in6); addr = (struct sockaddr*) &addr6; } else { size = sizeof(struct sockaddr_in); addr = (struct sockaddr*) &addr4; } if (!net_initialized) net_initialize(); ret = WSAStringToAddressA((char*) src, af, NULL, addr, &size); if (ret == -1) { return -1; } if (af == AF_INET6) { memcpy(dst, &addr6.sin6_addr, sizeof(addr6.sin6_addr)); } else { memcpy(dst, &addr4.sin_addr, sizeof(addr4.sin_addr)); } return 1; #else return inet_pton(af, src, dst); #endif }
static int net_connect_job_schedule(struct net_connect_handle* handle, struct ip_addr_encap* addr) { struct net_connect_job* job; struct sockaddr_in* addr4; struct sockaddr_in6* addr6; if (addr->af == AF_INET6 && !net_is_ipv6_supported()) { LOG_TRACE("net_connect_job_schedule(): Skipping IPv6 support since IPv6 is not supported."); return 0; } else { job = hub_malloc_zero(sizeof(struct net_connect_job)); job->handle = handle; if (addr->af == AF_INET6) { addr6 = (struct sockaddr_in6*) &job->addr; LOG_TRACE("net_connect_job_schedule(): Scheduling IPv6 connect job."); addr6->sin6_family = AF_INET6; addr6->sin6_port = htons(handle->port); memcpy(&addr6->sin6_addr, &addr->internal_ip_data.in6, sizeof(struct in6_addr)); // prepend job->next = handle->job6; handle->job6 = job; } else { addr4 = (struct sockaddr_in*) &job->addr; LOG_TRACE("net_connect_job_schedule(): Scheduling IPv4 connect job."); addr4->sin_family = AF_INET; addr4->sin_port = htons(handle->port); memcpy(&addr4->sin_addr, &addr->internal_ip_data.in, sizeof(struct in_addr)); // prepend job->next = handle->job4; handle->job4 = job; } } return 1; }
struct hub_info* hub_start_service(struct hub_config* config) { struct hub_info* hub = 0; int ipv6_supported; hub = hub_malloc_zero(sizeof(struct hub_info)); if (!hub) { LOG_FATAL("Unable to allocate memory for hub"); return 0; } hub->tm_started = time(0); ipv6_supported = net_is_ipv6_supported(); if (ipv6_supported) LOG_DEBUG("IPv6 supported."); else LOG_DEBUG("IPv6 not supported."); 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...", net_get_local_address(hub->server->sd), config->server_port); #ifdef SSL_SUPPORT if (!load_ssl_certificates(hub, config)) { hub_free(hub); return 0; } #endif hub->config = config; hub->users = NULL; hub->muxes = list_create(); hub->users = uman_init(); if (!hub->users) { net_con_close(hub->server); hub_free(hub); return 0; } if (event_queue_initialize(&hub->queue, hub_event_dispatcher, (void*) hub) == -1) { net_con_close(hub->server); uman_shutdown(hub->users); hub_free(hub); return 0; } hub->recvbuf = hub_malloc(MAX_RECV_BUF); 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->users); hub_free(hub); return 0; } hub->logout_info = (struct linked_list*) list_create(); server_alt_port_start(hub, config); hub->status = hub_status_running; g_hub = hub; if (net_backend_get_timeout_queue()) { hub->stats.timeout = hub_malloc_zero(sizeof(struct timeout_evt)); timeout_evt_initialize(hub->stats.timeout, hub_timer_statistics, hub); timeout_queue_insert(net_backend_get_timeout_queue(), hub->stats.timeout, TIMEOUT_STATS); } // Start the hub command sub-system hub->commands = command_initialize(hub); return hub; }