static void socket_connect(MVMThreadContext *tc, MVMOSHandle *h, MVMString *host, MVMint64 port) { MVMIOSyncSocketData *data = (MVMIOSyncSocketData *)h->body.data; if (!data->ss.handle) { struct sockaddr *dest = resolve_host_name(tc, host, port); uv_tcp_t *socket = malloc(sizeof(uv_tcp_t)); uv_connect_t *connect = malloc(sizeof(uv_connect_t)); int r; data->ss.cur_tc = tc; connect->data = data; if ((r = uv_tcp_init(tc->loop, socket)) < 0 || (r = uv_tcp_connect(connect, socket, dest, on_connect)) < 0) { free(socket); free(connect); free(dest); MVM_exception_throw_adhoc(tc, "Failed to connect: %s", uv_strerror(r)); } uv_ref((uv_handle_t *)socket); uv_run(tc->loop, UV_RUN_DEFAULT); data->ss.handle = (uv_stream_t *)socket; free(connect); free(dest); } else { MVM_exception_throw_adhoc(tc, "Socket is already bound or connected"); } }
static void socket_bind(MVMThreadContext *tc, MVMOSHandle *h, MVMString *host, MVMint64 port) { MVMIOSyncSocketData *data = (MVMIOSyncSocketData *)h->body.data; if (!data->ss.handle) { struct sockaddr *dest = resolve_host_name(tc, host, port); uv_tcp_t *socket = malloc(sizeof(uv_tcp_t)); int r; if ((r = uv_tcp_init(tc->loop, socket)) < 0 || (r = uv_tcp_bind(socket, dest, 0)) < 0) { free(socket); free(dest); MVM_exception_throw_adhoc(tc, "Failed to bind: %s", uv_strerror(r)); } free(dest); /* Start listening, but unref the socket so it won't get in the way of * other things we want to do on this event loop. */ socket->data = data; uv_listen((uv_stream_t *)socket, 1, on_connection); uv_unref((uv_handle_t *)socket); data->ss.handle = (uv_stream_t *)socket; } else { MVM_exception_throw_adhoc(tc, "Socket is already bound or connected"); } }
static int esp_tcp_connect(const char *host, int hostlen, int port, int *sockfd, const esp_tls_cfg_t *cfg) { int ret = -1; struct addrinfo *res = resolve_host_name(host, hostlen); if (!res) { return ret; } int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (fd < 0) { ESP_LOGE(TAG, "Failed to create socket (family %d socktype %d protocol %d)", res->ai_family, res->ai_socktype, res->ai_protocol); goto err_freeaddr; } *sockfd = fd; void *addr_ptr; if (res->ai_family == AF_INET) { struct sockaddr_in *p = (struct sockaddr_in *)res->ai_addr; p->sin_port = htons(port); addr_ptr = p; } else if (res->ai_family == AF_INET6) { struct sockaddr_in6 *p = (struct sockaddr_in6 *)res->ai_addr; p->sin6_port = htons(port); p->sin6_family = AF_INET6; addr_ptr = p; } else { ESP_LOGE(TAG, "Unsupported protocol family %d", res->ai_family); goto err_freesocket; } if (cfg) { if (cfg->timeout_ms >= 0) { struct timeval tv; ms_to_timeval(cfg->timeout_ms, &tv); setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); } if (cfg->non_block) { int flags = fcntl(fd, F_GETFL, 0); fcntl(fd, F_SETFL, flags | O_NONBLOCK); } } ret = connect(fd, addr_ptr, res->ai_addrlen); if (ret < 0 && !(errno == EINPROGRESS && cfg->non_block)) { ESP_LOGE(TAG, "Failed to connnect to host (errno %d)", errno); goto err_freesocket; } freeaddrinfo(res); return 0; err_freesocket: close(fd); err_freeaddr: freeaddrinfo(res); return ret; }
// Bind the UDP socket with given socket descriptor with error checking. void bind_UDP_socket() { memset((char *) &UDP_socket_address, 0, sizeof(struct sockaddr_in)); struct hostent *nunki_server_IP_address_list_raw = resolve_host_name(HOST_NAME); struct in_addr **nunki_server_IP_address_list = (struct in_addr **) nunki_server_IP_address_list_raw->h_addr_list; UDP_socket_address.sin_family = AF_INET; UDP_socket_address.sin_addr = **nunki_server_IP_address_list; UDP_socket_address.sin_port = htons(SERVER_UDP_PORT_NUMBER); if (bind(UDP_socket_descriptor, (struct sockaddr *) &UDP_socket_address, sizeof(UDP_socket_address)) < 0) { display_error_message_int("Error binding address for UDP socket ", UDP_socket_descriptor, BIND_TO_UDP_SOCKET_ERROR); } update_socket_info(UDP_socket_descriptor, &UDP_socket_address); }
// Connect to Client over the created TCP connection. void connect_to_client_over_TCP() { memset((char *) &client_TCP_socket_address, 0, sizeof(client_TCP_socket_address)); struct hostent *client_IP_address_list_raw = resolve_host_name(HOST_NAME); struct in_addr **client_IP_address_list = (struct in_addr **) client_IP_address_list_raw->h_addr_list; client_TCP_socket_address.sin_family = AF_INET; client_TCP_socket_address.sin_addr = **client_IP_address_list; client_TCP_socket_address.sin_port = htons(CLIENT_TCP_PORT_NUMBER); if (connect(TCP_socket_descriptor, (struct sockaddr *) &client_TCP_socket_address, sizeof(client_TCP_socket_address)) < 0) { display_error_message_int("Error connecting client over TCP socket ", TCP_socket_descriptor, CONNECT_TO_CLIENT_OVER_TCP_ERROR); } }
// Bind the TCP socket with given socket descriptor with error checking. void bind_TCP_socket() { memset((char *) &TCP_socket_address, 0, sizeof(struct sockaddr_in)); struct hostent *server_IP_address_list_raw = resolve_host_name(HOST_NAME); struct in_addr **server_IP_address_list = (struct in_addr **) server_IP_address_list_raw->h_addr_list; TCP_socket_address.sin_family = AF_INET; TCP_socket_address.sin_addr = **server_IP_address_list; TCP_socket_address.sin_port = htons(0); if (bind(TCP_socket_descriptor, (struct sockaddr *) &TCP_socket_address, sizeof(TCP_socket_address)) < 0) { display_error_message_int("Error binding address for TCP socket ", TCP_socket_descriptor, BIND_TO_TCP_SOCKET_ERROR); } update_socket_info(TCP_socket_descriptor, &TCP_socket_address); }
bool tcp_provider_connect(tcp_socket* tcpSocket, text host, uint16_t port) { struct sockaddr_in sa; *tcpSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(*tcpSocket == TCP_PROVIDER_INVALID_SOCKET) { NABTO_LOG_ERROR(("Unable to connect to TCP relay service!")); return false; } { uint32_t hostIp = resolve_host_name(host); if(hostIp == 0) { NABTO_LOG_ERROR(("Unable to resolve host!")); return false; } sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(hostIp); sa.sin_port = htons(port); if(connect(*tcpSocket, (struct sockaddr*)&sa, sizeof(sa))) { closesocket(*tcpSocket); *tcpSocket = TCP_PROVIDER_INVALID_SOCKET; NABTO_LOG_ERROR(("Unable to connect to host!")); return false; } } { // If iMode!=0, non-blocking mode is enabled. u_long iMode = 1; ioctlsocket(*tcpSocket, FIONBIO, &iMode); } NABTO_LOG_TRACE(("Connection to TCP relay service established.")); return true; }