X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2FIOHandler%2FIOSockets.c;h=63a4115ebb49843dc307ecc817b8e033806a9b8e;hb=982a3a5a1770bbd826d8cf0e136d7a32b586065a;hp=b844d64f8228240729807aa6fece42c7474dec3c;hpb=78c9b3cbb2ecafa3b275c3eeafcf80796b7b3138;p=NextIRCd.git diff --git a/src/IOHandler/IOSockets.c b/src/IOHandler/IOSockets.c index b844d64..63a4115 100644 --- a/src/IOHandler/IOSockets.c +++ b/src/IOHandler/IOSockets.c @@ -23,9 +23,12 @@ #include "IOSSLBackend.h" #ifdef WIN32 +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif #define _WIN32_WINNT 0x501 -#include #include +#include #include #else #include @@ -91,12 +94,12 @@ static void iosockets_init_engine() { void _init_sockets() { #ifdef WIN32 WSADATA wsaData; - int iResult; + int iResult; //Initialize Winsock - iResult = WSAStartup(MAKEWORD(2,2), &wsaData); - if(iResult != 0){ - iolog_trigger(IOLOG_ERROR, "WSAStartup returned error code: %d", iResult); - } + iResult = WSAStartup(MAKEWORD(2,2), &wsaData); + if(iResult != 0){ + iolog_trigger(IOLOG_ERROR, "WSAStartup returned error code: %d", iResult); + } #endif iosockets_init_engine(); @@ -551,7 +554,7 @@ static void iosocket_listen_finish(struct _IOSocket *iosock) { if((iosock->socket_flags & IOSOCKETFLAG_IPV6SOCKET)) { struct sockaddr_in6 *ip6bind = (void*) iosock->bind.addr.address; ip6bind->sin6_family = AF_INET6; - ip6bind->sin6_port = htons(0); + ip6bind->sin6_port = htons(iosock->port); int opt = 1; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt)); @@ -560,7 +563,7 @@ static void iosocket_listen_finish(struct _IOSocket *iosock) { } else { struct sockaddr_in *ip4bind = (void*) iosock->bind.addr.address; ip4bind->sin_family = AF_INET; - ip4bind->sin_port = htons(0); + ip4bind->sin_port = htons(iosock->port); int opt = 1; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt)); @@ -591,6 +594,7 @@ struct _IOSocket *iosocket_accept_client(struct _IOSocket *iosock) { } new_iosocket->iosocket = new_iosock; new_iosocket->status = IOSOCKET_CONNECTED; + new_iosocket->data = iosock; new_iosock->parent = new_iosocket; new_iosock->socket_flags |= IOSOCKETFLAG_PARENT_PUBLIC | IOSOCKETFLAG_INCOMING | (iosock->socket_flags & IOSOCKETFLAG_IPV6SOCKET); @@ -632,6 +636,9 @@ struct _IOSocket *iosocket_accept_client(struct _IOSocket *iosock) { new_iosock->socket_flags |= IOSOCKETFLAG_SSLSOCKET; iossl_client_accepted(iosock, new_iosock); + } else { + //initialize readbuf + iosocket_increase_buffer(&iosock->readbuf, 1024); } iosocket_activate(new_iosock); @@ -753,7 +760,7 @@ struct IOSocket *iosocket_listen_ssl(const char *hostname, unsigned int port, co struct IOSocket *iosocket_listen_ssl_flags(const char *hostname, unsigned int port, const char *certfile, const char *keyfile, iosocket_callback *callback, int flags) { struct IOSocket *iosocket = iosocket_listen_flags(hostname, port, callback, flags); struct _IOSocket *iosock = iosocket->iosocket; - iosock->socket_flags |= IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_HANDSHAKE; + iosock->socket_flags |= IOSOCKETFLAG_SSLSOCKET; iossl_listen(iosock, certfile, keyfile); return iosocket; } @@ -793,6 +800,22 @@ void iosocket_close(struct IOSocket *iosocket) { iogc_add(iosocket); } +struct IODNSAddress *iosocket_get_remote_addr(struct IOSocket *iosocket) { + if(iosock->socket_flags & IOSOCKETFLAG_PENDING_DESTDNS) + return NULL; + if(!iosock->dest.addr.addresslen) + return NULL; + return &iosock->dest.addr; +} + +struct IODNSAddress *iosocket_get_local_addr(struct IOSocket *iosocket) { + if(iosock->socket_flags & IOSOCKETFLAG_PENDING_BINDDNS) + return NULL; + if(!iosock->bind.addr.addresslen) + return NULL; + return &iosock->bind.addr; +} + static int iosocket_try_write(struct _IOSocket *iosock) { if(!iosock->writebuf.bufpos && !(iosock->socket_flags & IOSOCKETFLAG_SSL_WRITEHS)) return 0; @@ -809,7 +832,7 @@ static int iosocket_try_write(struct _IOSocket *iosock) { res = 0; } else { iosock->writebuf.bufpos -= res; - if((iosock->socket_flags & (IOSOCKETFLAG_ACTIVE & IOSOCKETFLAG_SHUTDOWN)) == IOSOCKETFLAG_ACTIVE) + if((iosock->socket_flags & (IOSOCKETFLAG_ACTIVE | IOSOCKETFLAG_SHUTDOWN)) == IOSOCKETFLAG_ACTIVE) engine->update(iosock); } return res; @@ -859,6 +882,28 @@ void iosocket_printf(struct IOSocket *iosocket, const char *text, ...) { } +int iosocket_wants_reads(struct _IOSocket *iosock) { + if((iosock->socket_flags & (IOSOCKETFLAG_SSL_READHS | IOSOCKETFLAG_SSL_WRITEHS))) + return ((iosock->socket_flags & IOSOCKETFLAG_SSL_WANTWRITE) ? 0 : 1); + if(!(iosock->socket_flags & IOSOCKETFLAG_OVERRIDE_WANT_RW)) + return 1; + else if((iosock->socket_flags & IOSOCKETFLAG_OVERRIDE_WANT_R)) + return 1; + return 0; +} +int iosocket_wants_writes(struct _IOSocket *iosock) { + if((iosock->socket_flags & (IOSOCKETFLAG_SSL_READHS | IOSOCKETFLAG_SSL_WRITEHS))) + return ((iosock->socket_flags & IOSOCKETFLAG_SSL_WANTWRITE) ? 1 : 0); + if(!(iosock->socket_flags & IOSOCKETFLAG_OVERRIDE_WANT_RW)) { + if(iosock->writebuf.bufpos || (iosock->socket_flags & IOSOCKETFLAG_CONNECTING)) + return 1; + else + return 0; + } else if((iosock->socket_flags & IOSOCKETFLAG_OVERRIDE_WANT_W)) + return 1; + return 0; +} + static void iosocket_trigger_event(struct IOSocketEvent *event) { if(!event->socket->callback) @@ -888,7 +933,12 @@ void iosocket_events_callback(struct _IOSocket *iosock, int readable, int writea //incoming SSL connection accepted iosock->socket_flags &= ~IOSOCKETFLAG_SSL_HANDSHAKE; callback_event.type = IOSOCKETEVENT_ACCEPT; - callback_event.data.accept_socket = iosock->parent; + callback_event.data.accept_socket = iosock->parent; + struct _IOSocket *parent_socket = iosocket->data; + callback_event.socket = parent_socket->parent; + + //initialize readbuf + iosocket_increase_buffer(&iosock->readbuf, 1024); } else { //incoming SSL connection failed, simply drop iosock->socket_flags |= IOSOCKETFLAG_DEAD; @@ -965,15 +1015,26 @@ void iosocket_events_callback(struct _IOSocket *iosock, int readable, int writea else if((iosock->socket_flags & IOSOCKETFLAG_SSL_WRITEHS)) ssl_rehandshake = 2; } + iosocketevents_callback_retry_read: if((readable && ssl_rehandshake == 0) || ssl_rehandshake == 1) { int bytes; - if(iosock->readbuf.buflen - iosock->readbuf.bufpos >= 128) - iosocket_increase_buffer(&iosock->readbuf, iosock->readbuf.buflen + 1024); + if(iosock->readbuf.buflen - iosock->readbuf.bufpos <= 128) { + int addsize; + if(iosock->readbuf.buflen >= 2048) + addsize = 1024; + else + addsize = iosock->readbuf.buflen; + if(addsize == 0) { + iolog_trigger(IOLOG_WARNING, "readbuf length is 0 when trying to read from fd %d", iosock->fd); + addsize = 512; + } + iosocket_increase_buffer(&iosock->readbuf, iosock->readbuf.buflen + addsize); + } if((iosock->socket_flags & IOSOCKETFLAG_SSLSOCKET)) bytes = iossl_read(iosock, iosock->readbuf.buffer + iosock->readbuf.bufpos, iosock->readbuf.buflen - iosock->readbuf.bufpos); else bytes = recv(iosock->fd, iosock->readbuf.buffer + iosock->readbuf.bufpos, iosock->readbuf.buflen - iosock->readbuf.bufpos, 0); - + if(bytes <= 0) { if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_READHS)) == (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_READHS)) { ssl_rehandshake = 1; @@ -987,6 +1048,7 @@ void iosocket_events_callback(struct _IOSocket *iosock, int readable, int writea int i; iolog_trigger(IOLOG_DEBUG, "received %d bytes (fd: %d). readbuf position: %d", bytes, iosock->fd, iosock->readbuf.bufpos); iosock->readbuf.bufpos += bytes; + int retry_read = (iosock->readbuf.bufpos == iosock->readbuf.buflen); callback_event.type = IOSOCKETEVENT_RECV; if(iosocket->parse_delimiter) { @@ -1035,6 +1097,8 @@ void iosocket_events_callback(struct _IOSocket *iosock, int readable, int writea callback_event.type = IOSOCKETEVENT_IGNORE; } else callback_event.data.recv_buf = &iosock->readbuf; + if(retry_read) + goto iosocketevents_callback_retry_read; } } if((writeable && ssl_rehandshake == 0) || ssl_rehandshake == 2) {