/* * Torsocks call for close(2). */ LIBC_CLOSE_RET_TYPE tsocks_close(LIBC_CLOSE_SIG) { struct connection *conn; DBG("[close] Close caught for fd %d", fd); connection_registry_lock(); conn = connection_find(fd); if (conn) { /* * Remove from the registry so it's not visible anymore and thus using * it without lock. */ connection_remove(conn); } connection_registry_unlock(); /* * Put back the connection reference. If the refcount get to 0, the * connection pointer is destroyed. */ if (conn) { DBG("[close] Close connection putting back ref"); connection_put_ref(conn); } /* * Let the log system detect when the log file fd is about to be * closed and clean up. */ log_fd_close_notify(fd); /* Return the original libc close. */ return tsocks_libc_close(fd); }
int main(void) { BOOL bRet; HANDLE hRet; wsa_init(); iocp = w_iocp_create(); DIE(iocp == NULL, "w_iocp_create"); /* Create server socket. */ listenfd = tcp_create_listener(ECHO_LISTEN_PORT, DEFAULT_LISTEN_BACKLOG); DIE(listenfd == INVALID_SOCKET, "tcp_create_listener"); hRet = w_iocp_add_handle(iocp, (HANDLE) listenfd); DIE(hRet != iocp, "w_iocp_add_handle"); /* Use AcceptEx to schedule new connection acceptance. */ create_iocp_accept(); dlog(LOG_INFO, "Server waiting for connections on port %d\n", ECHO_LISTEN_PORT); /* server main loop */ while (1) { OVERLAPPED *ovp; ULONG_PTR key; DWORD bytes; /* Wait for overlapped I/O. */ bRet = w_iocp_wait(iocp, &bytes, &key, &ovp); if (bRet == FALSE) { DWORD err; err = GetLastError(); if (err == ERROR_NETNAME_DELETED) { connection_remove((struct connection *) key); continue; } DIE(bRet == FALSE, "w_iocp_wait"); } /* * Switch I/O notification types. Consider * - new connection requests (on server socket); * - socket communication (on connection sockets). */ if (key == listenfd) { dlog(LOG_DEBUG, "New connection\n"); handle_new_connection(ovp); } else { handle_aio((struct connection *) key, bytes, ovp); } } wsa_cleanup(); return 0; }
static void connection_free_all(qq_data *qd) { qq_connection *ret = NULL; GSList *entry = qd->openconns; while(entry) { ret = entry->data; connection_remove(qd, ret->fd); entry = qd->openconns; } }
static void connection_free_all(struct fetion_account_data *sip) { struct sip_connection *ret = NULL; GSList *entry = sip->openconns; while (entry) { ret = entry->data; connection_remove(sip, ret->fd); entry = sip->openconns; } }
static void connection_complete_socket_receive(struct connection *conn, WSAOVERLAPPED *ovp) { BOOL bRet; DWORD flags; bRet = WSAGetOverlappedResult( conn->sockfd, ovp, &conn->bytes_recv, FALSE, &flags); DIE(bRet == FALSE, "WSAGetOverlappedResult"); /* In case of no bytes received, consider connection terminated. */ if (conn->bytes_recv == 0) { connection_remove(conn); return; } connection_prepare_socket_send(conn); connection_schedule_socket_send(conn); }
static void connection_complete_socket_send(struct connection *conn, WSAOVERLAPPED *ovp) { /* Closing the socket also removes it from Completion port. */ connection_remove(conn); }