/****************************************************************************** * NETCON_secure_connect * Initiates a secure connection over an existing plaintext connection. */ DWORD NETCON_secure_connect(netconn_t *connection, server_t *server) { DWORD res; /* can't connect if we are already connected */ if(connection->secure) { ERR("already connected\n"); return ERROR_INTERNET_CANNOT_CONNECT; } if(server != connection->server) { server_release(connection->server); server_addref(server); connection->server = server; } /* connect with given TLS options */ res = netcon_secure_connect_setup(connection, FALSE); if (res == ERROR_SUCCESS) return res; /* FIXME: when got version alert and FIN from server */ /* fallback to connect without TLSv1.1/TLSv1.2 */ if (res == ERROR_INTERNET_SECURITY_CHANNEL_ERROR && have_compat_cred_handle) { closesocket(connection->socket); res = create_netconn_socket(connection->server, connection, 500); if (res != ERROR_SUCCESS) return res; res = netcon_secure_connect_setup(connection, TRUE); } return res; }
void free_netconn(netconn_t *netconn) { server_release(netconn->server); #ifdef SONAME_LIBSSL if (netconn->ssl_s) { pSSL_shutdown(netconn->ssl_s); pSSL_free(netconn->ssl_s); } #endif closesocket(netconn->socketFD); heap_free(netconn); }
void free_netconn(netconn_t *netconn) { server_release(netconn->server); if (netconn->secure) { heap_free(netconn->peek_msg_mem); netconn->peek_msg_mem = NULL; netconn->peek_msg = NULL; netconn->peek_len = 0; heap_free(netconn->ssl_buf); netconn->ssl_buf = NULL; heap_free(netconn->extra_buf); netconn->extra_buf = NULL; netconn->extra_len = 0; if (SecIsValidHandle(&netconn->ssl_ctx)) DeleteSecurityContext(&netconn->ssl_ctx); } heap_free(netconn); }
void lt_main(void *arg) { int fd, opt = 1; proxy_server *srv = (proxy_server*)arg; lthread_t *lt_accept = NULL; struct sockaddr cin = {0}; socklen_t addrlen = sizeof(struct sockaddr); proxy_conn_t *proxy = NULL; DEFINE_LTHREAD; lthread_detach(); srv->listen_fd = create_listener("0.0.0.0", 9000); if(srv->listen_fd < 0) { exit(1); } fprintf(stderr, "listener creating :9000\n"); lthread_create(<_accept, (void*)lt_accept_loop, (void*)srv); while(!srv->is_die) { fd = lthread_accept(srv->listen_fd, &cin, &addrlen); if(fd < 0) { perror("accept error"); break; } if(srv->quiting) { lthread_close(fd); break; } if(srv->is_die) { //already die, close and break lthread_close(fd); fprintf(stderr, "server already die :9000\n"); break; } if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)) == -1) { perror("failed to set SOREUSEADDR on socket"); break; } fprintf(stderr, "accept new client\n"); proxy = proxy_conn_create(fd, 0); if(0 != chan_send(srv->accepts_ch, proxy)) { //send failed, free proxy proxy_conn_free(proxy); break; } //yield myself lthread_sleep((uint64_t)0); } if(-1 != srv->listen_fd) { close(srv->listen_fd); srv->listen_fd = -1; } if(!srv->is_die) { srv->is_die = 1; chan_close(srv->die_ch); fprintf(stderr, "srv die\n"); } fprintf(stderr, "lt_accept end\n"); lthread_join(lt_accept, NULL, LTHREAD_FOREVER); //server release server_release(srv); }