int tcp_destruct(tcp_sock_t *tcp) { ASSERT(tcp); if (tcp->initialized == 1) tcp_exit(tcp); return ip_destruct(&tcp->ip); }
int ssl_close(http_t *client) { if (client->ssl_enabled) { gnutls_bye(client->ssl, GNUTLS_SHUT_WR); gnutls_deinit(client->ssl); } return tcp_exit(&client->tcp); }
/** * \brief Initialize client TCP socket. * * @param[out] sock socket number * @param[in] ip ip address of TCP server * @param[in] port port number of TCP server * @return 0 if ok, <0 if error occured */ int tcp_client_init(void **sock, unsigned int ip, unsigned short port) { struct _ip_socket_struct *s; struct sockaddr_in addr; s = (struct _ip_socket_struct *)malloc(sizeof(struct _ip_socket_struct)); if (s == NULL) { return -11; } // initialize socket dll (only Windows): #ifdef OS_WIN { WORD vreq; WSADATA wsa; vreq = MAKEWORD(2, 0); if (WSAStartup(vreq, &wsa) != 0) { free(s); return -1; } } #endif // create socket: #ifdef OS_UNIX s->ossock = socket(PF_INET, SOCK_STREAM, 0); if (s->ossock < 0) { free(s); return -2; } #endif #ifdef OS_WIN s->ossock = socket(PF_INET, SOCK_STREAM, 0); if (s->ossock == INVALID_SOCKET) { WSACleanup(); free(s); return -2; } #endif // connect with server: addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(ip); addr.sin_port = htons(port); if ((connect(s->ossock, (struct sockaddr *)&addr, (size_t)sizeof(addr)))) { tcp_exit(s); return -3; } *sock = s; return 0; }
/* Disconnect and some other clean up. */ int http_exit(http_t *client) { ASSERT(client); if (!client->initialized) return 0; client->initialized = 0; if (client->ssl_enabled) ssl_exit(client); return tcp_exit(&client->tcp); }
int ssl_close(http_t *client) { if (client->ssl_enabled) { /* SSL/TLS close_notify */ SSL_shutdown(client->ssl); /* Clean up. */ SSL_free(client->ssl); SSL_CTX_free(client->ssl_ctx); } return tcp_exit(&client->tcp); }
void gen_http_drv_ready_output(ErlDrvData handle, ErlDrvEvent event) { HTTP* d = (HTTP*) handle; if(d->mode == REQUEST_MODE && d->state == CONNECTING_STATE) { accept_connection(d); return; } SysIOVec* vec; int vlen = 0; size_t written; vec = driver_peekq(d->port, &vlen); if(!vec || !vlen) { deactivate_write(d); return; } written = writev(d->socket, (const struct iovec *)vec, vlen > IOV_MAX ? IOV_MAX : vlen); if(vlen > IOV_MAX) { fprintf(stderr, "Buffer overloaded: %d, %d\r\n", vlen, (int)(driver_sizeq(d->port) - written)); } if(written == -1) { if((errno != EWOULDBLOCK) && (errno != EINTR) && (errno != EAGAIN)) { // fprintf(stderr, "Error in writev: %s, %d bytes left\r\n", strerror(errno), (int)driver_sizeq(d->port)); tcp_exit(d); return; } } else { ErlDrvSizeT rest = driver_deq(d->port, written); if(rest == 0) { ErlDrvTermData reply[] = { ERL_DRV_ATOM, atom_http, ERL_DRV_PORT, driver_mk_port(d->port), ERL_DRV_ATOM, atom_empty, ERL_DRV_TUPLE, 3 }; pid_list_send(d->exhausted, d->port, reply, sizeof(reply) / sizeof(reply[0])); pid_list_free(&d->exhausted); set_busy_port(d->port, 0); } // fprintf(stderr, "Network write: %d (%d)\r\n", (int)written, (int)rest); } }
DTrack2::~DTrack2(void) { // release buffer: if(d_udpbuf){ free(d_udpbuf); } // release sockets: if(d_udpsock){ udp_exit(d_udpsock); d_udpsock = NULL; } if(d_tcpsock){ tcp_exit(d_tcpsock); d_tcpsock = NULL; } }
/* On error tcp_exit() is called by upper layers. */ int tcp_init(tcp_sock_t *tcp, char *msg, int verbose) { int rc = 0; char host[NI_MAXHOST]; struct timeval sv; struct sockaddr sa; socklen_t salen; ASSERT(tcp); do { int sd; TRY(local_set_params(tcp)); TRY(ip_init(&tcp->ip)); if (tcp->ip.type != TYPE_TCP) return RC_IP_BAD_PARAMETER; sd = socket(AF_INET, SOCK_STREAM, 0); if (sd == -1) { logit(LOG_ERR, "Error creating client socket: %s", strerror(errno)); rc = RC_IP_SOCKET_CREATE_ERROR; break; } /* Call to socket() OK, allow tcp_exit() to run to * prevent socket leak if any of the below calls fail. */ tcp->ip.socket = sd; tcp->initialized = 1; if (tcp->ip.bound == 1) { if (bind(sd, (struct sockaddr *)&tcp->ip.local_addr, sizeof(struct sockaddr_in)) < 0) { logit(LOG_WARNING, "Failed binding client socket to local address: %s", strerror(errno)); rc = RC_IP_SOCKET_BIND_ERROR; break; } } /* Attempt to set TCP timers, silently fall back to OS defaults */ sv.tv_sec = tcp->ip.timeout / 1000; sv.tv_usec = (tcp->ip.timeout % 1000) * 1000; setsockopt(tcp->ip.socket, SOL_SOCKET, SO_RCVTIMEO, &sv, sizeof(sv)); setsockopt(tcp->ip.socket, SOL_SOCKET, SO_SNDTIMEO, &sv, sizeof(sv)); sa = tcp->ip.remote_addr; salen = tcp->ip.remote_len; if (!getnameinfo(&sa, salen, host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST)) { if (verbose > 0) logit(LOG_INFO, "%s, connecting to %s (%s:%d)", msg, tcp->ip.p_remote_host_name, host, tcp->ip.port); } else logit(LOG_ERR, "%s, failed resolving %s!", msg, host); if (connect(sd, &sa, salen)) { if (!check_error(sd, tcp->ip.timeout)) break; /* OK */ logit(LOG_WARNING, "Failed connecting to remote server: %s", strerror(errno)); rc = RC_IP_CONNECT_FAILED; break; } } while (0); if (rc) { tcp_exit(tcp); return rc; } return 0; }