From e12753d2ec9db83ec08bb9db63902a82fb245cdd Mon Sep 17 00:00:00 2001 From: "Tomas Chvatal (scarabeus)" Date: Wed, 22 Oct 2008 22:50:54 +0200 Subject: X --- src/net/tcp.c | 547 ++++++++++++++++++++++++++++------------------------------ 1 file changed, 266 insertions(+), 281 deletions(-) (limited to 'src/net/tcp.c') diff --git a/src/net/tcp.c b/src/net/tcp.c index aae5e3c..87c97ba 100755 --- a/src/net/tcp.c +++ b/src/net/tcp.c @@ -16,386 +16,371 @@ #include #include #include -#include +#include #include #include "tcp.h" -sock_tcp_t* newSockTcp(int proto) +sock_tcp_t * +newSockTcp(int proto) { - sock_tcp_t *new; + sock_tcp_t *new; - new = malloc( sizeof(sock_tcp_t) ); - memset(new, 0, sizeof(sock_tcp_t)); - new->proto = proto; + new = malloc(sizeof(sock_tcp_t)); + memset(new, 0, sizeof(sock_tcp_t)); + new->proto = proto; - return new; + return new; } -void destroySockTcp(sock_tcp_t *p) +void +destroySockTcp(sock_tcp_t * p) { - assert( p != NULL ); - free(p); + assert(p != NULL); + free(p); } -sock_tcp_t* bindTcpSocket(char *address, int port, int proto) +sock_tcp_t * +bindTcpSocket(char *address, int port, int proto) { - sock_tcp_t *new; - unsigned long param_setsock = 1; - int len; - int ret; + sock_tcp_t *new; + unsigned long param_setsock = 1; + int len; + int ret; - assert( port > 0 && port < 65535 ); + assert(port > 0 && port < 65535); - new = newSockTcp(proto); - ret = -1; // no Warnnings + new = newSockTcp(proto); + ret = -1; // no Warnnings - assert( new != NULL ); + assert(new != NULL); - if( new->proto == PROTO_TCPv4 ) - { - new->sock = socket(AF_INET, SOCK_STREAM, 0); - } + if (new->proto == PROTO_TCPv4) { + new->sock = socket(AF_INET, SOCK_STREAM, 0); + } #ifdef SUPPORT_IPv6 - if( new->proto == PROTO_TCPv6 ) - { - new->sock = socket(AF_INET6, SOCK_STREAM, 0); - } -#endif - - if( new->sock < 0 ) - { - fprintf(stderr, _("Unable to create socket when connecting!\n")); - destroySockTcp(new); - return NULL; - } - - setsockopt(new->sock, SOL_SOCKET, SO_REUSEADDR, (char *) ¶m_setsock, sizeof (param_setsock)); - - if( new->proto == PROTO_TCPv4 ) - { - new->sockAddr.sin_family = AF_INET; - inet_pton(AF_INET, address, &(new->sockAddr.sin_addr)); - new->sockAddr.sin_port = htons(port); - - len = sizeof(new->sockAddr); - ret = bind(new->sock, (struct sockaddr *)&new->sockAddr, len); - } + if (new->proto == PROTO_TCPv6) { + new->sock = socket(AF_INET6, SOCK_STREAM, 0); + } +#endif + + if (new->sock < 0) { + fprintf(stderr, _("Unable to create socket when connecting!\n")); + destroySockTcp(new); + return NULL; + } + + setsockopt(new->sock, SOL_SOCKET, SO_REUSEADDR, (char *) ¶m_setsock, + sizeof(param_setsock)); + + if (new->proto == PROTO_TCPv4) { + new->sockAddr.sin_family = AF_INET; + inet_pton(AF_INET, address, &(new->sockAddr.sin_addr)); + new->sockAddr.sin_port = htons(port); + + len = sizeof(new->sockAddr); + ret = bind(new->sock, (struct sockaddr *) &new->sockAddr, len); + } #ifdef SUPPORT_IPv6 - if( new->proto == PROTO_TCPv6 ) - { - new->sockAddr6.sin6_family = AF_INET6; - //new->sockAddr.sin_addr.s_addr = htonl(INADDR_ANY); - inet_pton(AF_INET6, address, &(new->sockAddr6.sin6_addr)); - new->sockAddr6.sin6_port = htons(port); - - len = sizeof(new->sockAddr6); - ret = bind(new->sock, (struct sockaddr *)&new->sockAddr6, len); - } + if (new->proto == PROTO_TCPv6) { + new->sockAddr6.sin6_family = AF_INET6; + //new->sockAddr.sin_addr.s_addr = htonl(INADDR_ANY); + inet_pton(AF_INET6, address, &(new->sockAddr6.sin6_addr)); + new->sockAddr6.sin6_port = htons(port); + + len = sizeof(new->sockAddr6); + ret = bind(new->sock, (struct sockaddr *) &new->sockAddr6, len); + } #endif - if( ret < 0 ) - { - fprintf(stderr, _("Unable to bint to port: %d\n"), port); - destroySockTcp(new); - return NULL; - } + if (ret < 0) { + fprintf(stderr, _("Unable to bint to port: %d\n"), port); + destroySockTcp(new); + return NULL; + } - listen(new->sock, 5); + listen(new->sock, 5); - return new; + return new; } -sock_tcp_t* getTcpNewClient(sock_tcp_t *p) +sock_tcp_t * +getTcpNewClient(sock_tcp_t * p) { - sock_tcp_t *new; - int client_len; + sock_tcp_t *new; + int client_len; + + assert(p != NULL); + assert(p->sock >= 0); - assert( p != NULL ); - assert( p->sock >= 0 ); + new = newSockTcp(p->proto); - new = newSockTcp(p->proto); + if (new->proto == PROTO_TCPv4) { + client_len = sizeof(new->sockAddr); - if( new->proto == PROTO_TCPv4 ) - { - client_len = sizeof(new->sockAddr); - - new->sock = accept(p->sock, (struct sockaddr *)&new->sockAddr, - (socklen_t *)&client_len); - } + new->sock = accept(p->sock, (struct sockaddr *) &new->sockAddr, + (socklen_t *) & client_len); + } #ifdef SUPPORT_IPv6 - if( new->proto == PROTO_TCPv6 ) - { - client_len = sizeof(new->sockAddr6); - - new->sock = accept(p->sock, (struct sockaddr *)&new->sockAddr6, - (socklen_t *)&client_len); - } + if (new->proto == PROTO_TCPv6) { + client_len = sizeof(new->sockAddr6); + + new->sock = accept(p->sock, (struct sockaddr *) &new->sockAddr6, + (socklen_t *) & client_len); + } #endif - if( new->sock < 0 ) - { - //printf("XXX\n"); - destroySockTcp(new); - return NULL; - } + if (new->sock < 0) { + //printf("XXX\n"); + destroySockTcp(new); + return NULL; + } - return new; + return new; } -void getSockTcpIp(sock_tcp_t *p, char *str_ip, int len) +void +getSockTcpIp(sock_tcp_t * p, char *str_ip, int len) { - assert( p != NULL ); - assert( str_ip != NULL ); + assert(p != NULL); + assert(str_ip != NULL); + - - if( p->proto == PROTO_TCPv4 ) - { - inet_ntop(AF_INET, &(p->sockAddr.sin_addr), str_ip, len); - strcpy(str_ip, inet_ntoa(p->sockAddr.sin_addr)); - //printf("strcpy(str_ip, inet_ntoa(p->sockAddr.sin_addr));\n"); - } + if (p->proto == PROTO_TCPv4) { + inet_ntop(AF_INET, &(p->sockAddr.sin_addr), str_ip, len); + strcpy(str_ip, inet_ntoa(p->sockAddr.sin_addr)); + //printf("strcpy(str_ip, inet_ntoa(p->sockAddr.sin_addr));\n"); + } #ifdef SUPPORT_IPv6 - if( p->proto == PROTO_TCPv6 ) - { - inet_ntop(AF_INET6, &(p->sockAddr6.sin6_addr), str_ip, len); - } + if (p->proto == PROTO_TCPv6) { + inet_ntop(AF_INET6, &(p->sockAddr6.sin6_addr), str_ip, len); + } #endif } -int getSockTcpPort(sock_tcp_t *p) +int +getSockTcpPort(sock_tcp_t * p) { - assert( p != NULL ); + assert(p != NULL); - if( p->proto == PROTO_TCPv4 ) - { - return htons(p->sockAddr.sin_port); - } + if (p->proto == PROTO_TCPv4) { + return htons(p->sockAddr.sin_port); + } #ifdef SUPPORT_IPv6 - if( p->proto == PROTO_TCPv6 ) - { - return htons(p->sockAddr6.sin6_port); - } + if (p->proto == PROTO_TCPv6) { + return htons(p->sockAddr6.sin6_port); + } #endif - assert( ! _("Bad IP proto!") ); + assert(!_("Bad IP proto!")); - return -1; + return -1; } -sock_tcp_t* connectTcpSocket(char *ip, int port, int proto) +sock_tcp_t * +connectTcpSocket(char *ip, int port, int proto) { - sock_tcp_t *new; - int len; - int ret; + sock_tcp_t *new; + int len; + int ret; - assert( ip != NULL ); - assert( port > 0 && port < 65535 ); + assert(ip != NULL); + assert(port > 0 && port < 65535); - new = newSockTcp(proto); - ret = -1; // no Warnnings + new = newSockTcp(proto); + ret = -1; // no Warnnings - if( new->proto == PROTO_TCPv4 ) - { - new->sock = socket(AF_INET, SOCK_STREAM, 0); - } + if (new->proto == PROTO_TCPv4) { + new->sock = socket(AF_INET, SOCK_STREAM, 0); + } #ifdef SUPPORT_IPv6 - if( new->proto == PROTO_TCPv6 ) - { - new->sock = socket(AF_INET6, SOCK_STREAM, 0); - } -#endif - - if( new->sock < 0 ) - { - fprintf(stderr, _("Unable to create TCP socket!\n")); - destroySockTcp(new); - return NULL; - } - - if( new->proto == PROTO_TCPv4 ) - { - new->sockAddr.sin_family = AF_INET; - new->sockAddr.sin_addr.s_addr = inet_addr(ip); - new->sockAddr.sin_port = htons(port); - - len = sizeof(new->sockAddr); - ret = connect(new->sock, (struct sockaddr *)&new->sockAddr, len); - } + if (new->proto == PROTO_TCPv6) { + new->sock = socket(AF_INET6, SOCK_STREAM, 0); + } +#endif + + if (new->sock < 0) { + fprintf(stderr, _("Unable to create TCP socket!\n")); + destroySockTcp(new); + return NULL; + } + + if (new->proto == PROTO_TCPv4) { + new->sockAddr.sin_family = AF_INET; + new->sockAddr.sin_addr.s_addr = inet_addr(ip); + new->sockAddr.sin_port = htons(port); + + len = sizeof(new->sockAddr); + ret = connect(new->sock, (struct sockaddr *) &new->sockAddr, len); + } #ifdef SUPPORT_IPv6 - if( new->proto == PROTO_TCPv6 ) - { - new->sockAddr6.sin6_family = AF_INET6; - inet_pton(AF_INET6, ip, &(new->sockAddr6.sin6_addr)); - new->sockAddr6.sin6_port = htons(port); - - len = sizeof(new->sockAddr6); - ret = connect(new->sock, (struct sockaddr *)&new->sockAddr6, len); - } + if (new->proto == PROTO_TCPv6) { + new->sockAddr6.sin6_family = AF_INET6; + inet_pton(AF_INET6, ip, &(new->sockAddr6.sin6_addr)); + new->sockAddr6.sin6_port = htons(port); + + len = sizeof(new->sockAddr6); + ret = connect(new->sock, (struct sockaddr *) &new->sockAddr6, len); + } #endif - if( ret < 0 ) - { - fprintf(stderr, "Unable to connect on: \"%s\" port: \"%d\"\n", ip, port); - destroySockTcp(new); - return NULL; - } + if (ret < 0) { + fprintf(stderr, "Unable to connect on: \"%s\" port: \"%d\"\n", ip, + port); + destroySockTcp(new); + return NULL; + } - return new; + return new; } -int disableNagle(sock_tcp_t *p) +int +disableNagle(sock_tcp_t * p) { - int flag = 1; - - int result; - - result = setsockopt(p->sock, /* socket affected */ - IPPROTO_TCP, /* set option at TCP level */ - TCP_NODELAY, /* name of option */ - (char *) &flag, /* the cast is historical cruft */ - sizeof(int)); /* length of option value */ - + int flag = 1; + + int result; + + result = setsockopt(p->sock, /* socket affected */ + IPPROTO_TCP, /* set option at TCP level */ + TCP_NODELAY, /* name of option */ + (char *) &flag, /* the cast is historical cruft */ + sizeof(int)); /* length of option value */ + #if 0 - if( result < 0 ) - { - printf("disabled nagle error\n"); - } - else - { - printf("disabled nagle OK\n"); - } + if (result < 0) { + printf("disabled nagle error\n"); + } + else { + printf("disabled nagle OK\n"); + } #endif - return result; + return result; } -int setTcpSockNonBlock(sock_tcp_t *p) +int +setTcpSockNonBlock(sock_tcp_t * p) { - /* Set to nonblocking socket mode */ + /* Set to nonblocking socket mode */ #ifndef __WIN32__ - int oldFlag; + int oldFlag; - oldFlag = fcntl (p->sock, F_GETFL, 0); + oldFlag = fcntl(p->sock, F_GETFL, 0); - if( fcntl(p->sock, F_SETFL, oldFlag | O_NONBLOCK) == -1 ) - { - //printf("error setTcpSockNonBlock\n"); - return -1; - } + if (fcntl(p->sock, F_SETFL, oldFlag | O_NONBLOCK) == -1) { + //printf("error setTcpSockNonBlock\n"); + return -1; + } - //printf("setTcpSockNonBlock OK\n"); + //printf("setTcpSockNonBlock OK\n"); #else - unsigned long arg = 1; - // Operation is FIONBIO. Parameter is pointer on non-zero number. - if( ioctlsocket(p->sock, FIONBIO, &arg) == SOCKET_ERROR ) - { - WSACleanup(); - return -1; - } + unsigned long arg = 1; + // Operation is FIONBIO. Parameter is pointer on non-zero number. + if (ioctlsocket(p->sock, FIONBIO, &arg) == SOCKET_ERROR) { + WSACleanup(); + return -1; + } #endif - return 0; + return 0; } -int readTcpSocket(sock_tcp_t *p, void *address, int len) +int +readTcpSocket(sock_tcp_t * p, void *address, int len) { - assert( p != NULL ); - assert( address != NULL ); + assert(p != NULL); + assert(address != NULL); - return read(p->sock, address, len); + return read(p->sock, address, len); } -int writeTcpSocket(sock_tcp_t *p, void *address, int len) +int +writeTcpSocket(sock_tcp_t * p, void *address, int len) { - assert( p != NULL ); - assert( address != NULL ); + assert(p != NULL); + assert(address != NULL); - return write(p->sock, address, len); + return write(p->sock, address, len); } -void closeTcpSocket(sock_tcp_t *p) +void +closeTcpSocket(sock_tcp_t * p) { - assert( p != NULL ); + assert(p != NULL); - close(p->sock); - destroySockTcp(p); + close(p->sock); + destroySockTcp(p); } #if 0 #define MAX_CLIENTS 32 #define BUF_SIZE 512 -int main(int argc, char **argv) +int +main(int argc, char **argv) { - sock_tcp_t *sock; - sock_tcp_t *client[MAX_CLIENTS]; - int count_client; - int changed, i; - struct pollfd *tmp; - - sock = bindTcpSocket( "127.0.0.1", 2200, PROTO_TCPv4 ); - disableNagle(sock); - count_client = 0; - - for(;;) - { - tmp = malloc( (count_client+1) * sizeof(struct pollfd) ); - - tmp[0].fd = sock->sock; - tmp[0].events = POLLIN; - tmp[0].revents = 0; - - for( i = 0 ; i < count_client ; i++ ) - { - tmp[1+i].fd = client[i]->sock; - tmp[1+i].events = POLLIN; - tmp[1+i].revents = 0; - } - - changed = poll(tmp, count_client+1, 1000); - - if( tmp[0].revents & POLLIN != 0 ) - { - client[count_client] = getTcpNewClient(sock); - disableNagle(client[count_client]); - count_client++; - } - - for( i = 0 ; i < count_client ; i++ ) - { - if( tmp[1+i].revents & POLLIN != 0 ) - { - char buf[BUF_SIZE]; - int ret; - - ret = read(client[i]->sock, buf, BUF_SIZE); - - if( ret <= 0 ) - { - closeTcpSocket(client[i]); - - memmove(client + i, - client + (i+1), - ((count_client-1) - i) * sizeof(sock_tcp_t *) ); - - count_client--; - continue; - } - - write(client[i]->sock, buf, ret); - } - } - - free(tmp); - } + sock_tcp_t *sock; + sock_tcp_t *client[MAX_CLIENTS]; + int count_client; + int changed, i; + struct pollfd *tmp; + + sock = bindTcpSocket("127.0.0.1", 2200, PROTO_TCPv4); + disableNagle(sock); + count_client = 0; + + for (;;) { + tmp = malloc((count_client + 1) * sizeof(struct pollfd)); + + tmp[0].fd = sock->sock; + tmp[0].events = POLLIN; + tmp[0].revents = 0; + + for (i = 0; i < count_client; i++) { + tmp[1 + i].fd = client[i]->sock; + tmp[1 + i].events = POLLIN; + tmp[1 + i].revents = 0; + } + + changed = poll(tmp, count_client + 1, 1000); + + if (tmp[0].revents & POLLIN != 0) { + client[count_client] = getTcpNewClient(sock); + disableNagle(client[count_client]); + count_client++; + } + + for (i = 0; i < count_client; i++) { + if (tmp[1 + i].revents & POLLIN != 0) { + char buf[BUF_SIZE]; + int ret; + + ret = read(client[i]->sock, buf, BUF_SIZE); + + if (ret <= 0) { + closeTcpSocket(client[i]); + + memmove(client + i, + client + (i + 1), + ((count_client - 1) - i) * sizeof(sock_tcp_t *)); + + count_client--; + continue; + } + + write(client[i]->sock, buf, ret); + } + } + + free(tmp); + } } #endif - -- cgit v1.2.3