/* return 1 on success * return 0 on failure */ static int accept_connection(TCP_Server *TCP_server, sock_t sock) { if (!sock_valid(sock)) return 0; if (!set_socket_nonblock(sock)) { kill_sock(sock); return 0; } if (!set_socket_nosigpipe(sock)) { kill_sock(sock); return 0; } TCP_Secure_Connection *conn = &TCP_server->incomming_connection_queue[TCP_server->incomming_connection_queue_index % MAX_INCOMMING_CONNECTIONS]; if (conn->status != TCP_STATUS_NO_STATUS) kill_TCP_connection(conn); conn->status = TCP_STATUS_CONNECTED; conn->sock = sock; conn->next_packet_length = 0; ++TCP_server->incomming_connection_queue_index; return 1; }
/* return index on success * return -1 on failure */ static int accept_connection(TCP_Server *TCP_server, Socket sock) { if (!sock_valid(sock)) { return -1; } if (!set_socket_nonblock(sock)) { kill_sock(sock); return -1; } if (!set_socket_nosigpipe(sock)) { kill_sock(sock); return -1; } uint16_t index = TCP_server->incoming_connection_queue_index % MAX_INCOMING_CONNECTIONS; TCP_Secure_Connection *conn = &TCP_server->incoming_connection_queue[index]; if (conn->status != TCP_STATUS_NO_STATUS) { kill_TCP_secure_connection(conn); } conn->status = TCP_STATUS_CONNECTED; conn->sock = sock; conn->next_packet_length = 0; ++TCP_server->incoming_connection_queue_index; return index; }
int make_socket ( os_socket * sock, unsigned short port, c_bool stream, c_bool reuse, const os_sockaddr_storage * mcip, const char * address ) { int rc = -2; *sock = os_sockNew ((config.useIpv6 ? AF_INET6 : AF_INET), stream ? SOCK_STREAM : SOCK_DGRAM); if (! Q_VALID_SOCKET (*sock)) { print_sockerror ("socket"); return rc; } if (port && reuse && ((rc = set_reuse_options (*sock)) < 0)) { goto fail; } if ( (rc = set_rcvbuf (*sock) < 0) || (rc = set_sndbuf (*sock) < 0) || ((rc = maybe_set_dont_route (*sock)) < 0) || ((rc = bind_socket (*sock, port, address)) < 0) ) { goto fail; } if (! stream) { if ((rc = set_mc_options_transmit (*sock)) < 0) { goto fail; } } if (stream) { #ifdef SO_NOSIGPIPE set_socket_nosigpipe (*sock); #endif #ifdef TCP_NODELAY if (config.tcp_nodelay) { set_socket_nodelay (*sock); } #endif } if (mcip && ((rc = join_mcgroups (*sock, mcip)) < 0)) { goto fail; } return 0; fail: os_sockFree (*sock); *sock = Q_INVALID_SOCKET; return rc; }
/* Create new TCP connection to ip_port/public_key */ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, TCP_Proxy_Info *proxy_info) { if (networking_at_startup() != 0) { return NULL; } if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6) { return NULL; } uint8_t family = ip_port.ip.family; TCP_Proxy_Info default_proxyinfo; if (proxy_info == NULL) { default_proxyinfo.proxy_type = TCP_PROXY_NONE; proxy_info = &default_proxyinfo; } if (proxy_info->proxy_type != TCP_PROXY_NONE) { family = proxy_info->ip_port.ip.family; } Socket sock = net_socket(family, TOX_SOCK_STREAM, TOX_PROTO_TCP); if (!sock_valid(sock)) { return NULL; } if (!set_socket_nosigpipe(sock)) { kill_sock(sock); return 0; } if (!(set_socket_nonblock(sock) && connect_sock_to(sock, ip_port, proxy_info))) { kill_sock(sock); return NULL; } TCP_Client_Connection *temp = (TCP_Client_Connection *)calloc(sizeof(TCP_Client_Connection), 1); if (temp == NULL) { kill_sock(sock); return NULL; } temp->sock = sock; memcpy(temp->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(temp->self_public_key, self_public_key, CRYPTO_PUBLIC_KEY_SIZE); encrypt_precompute(temp->public_key, self_secret_key, temp->shared_key); temp->ip_port = ip_port; temp->proxy_info = *proxy_info; switch (proxy_info->proxy_type) { case TCP_PROXY_HTTP: temp->status = TCP_CLIENT_PROXY_HTTP_CONNECTING; proxy_http_generate_connection_request(temp); break; case TCP_PROXY_SOCKS5: temp->status = TCP_CLIENT_PROXY_SOCKS5_CONNECTING; proxy_socks5_generate_handshake(temp); break; case TCP_PROXY_NONE: temp->status = TCP_CLIENT_CONNECTING; if (generate_handshake(temp) == -1) { kill_sock(sock); free(temp); return NULL; } break; } temp->kill_at = unix_time() + TCP_CONNECTION_TIMEOUT; return temp; }