X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2FIOHandler%2FIOSockets.c;h=a361126b5540dd10a69160587c9fcfca49bc597c;hb=f40d2e60142d1cb141c46e63ed847b0d821ca920;hp=4a7da99c6b8618c6df169a7ff65ce3775e3e0034;hpb=2c089146f08538afd3a83998ba37cbb6dd2c8f6e;p=NextIRCd.git diff --git a/src/IOHandler/IOSockets.c b/src/IOHandler/IOSockets.c index 4a7da99..a361126 100644 --- a/src/IOHandler/IOSockets.c +++ b/src/IOHandler/IOSockets.c @@ -20,6 +20,7 @@ #include "IOSockets.h" #include "IOLog.h" #include "IODNSLookup.h" +#include "IOSSLBackend.h" #ifdef WIN32 #define _WIN32_WINNT 0x501 @@ -51,8 +52,6 @@ struct _IOSocket *iosocket_last = NULL; struct IOEngine *engine = NULL; -static void iosocket_activate(struct _IOSocket *iosock); -static void iosocket_deactivate(struct _IOSocket *iosock); static void iosocket_increase_buffer(struct IOSocketBuffer *iobuf, size_t required); static int iosocket_parse_address(const char *hostname, struct IODNSAddress *addr, int records); static int iosocket_lookup_hostname(struct _IOSocket *iosock, const char *hostname, int records, int bindaddr); @@ -92,12 +91,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(); @@ -147,20 +146,26 @@ void _free_socket(struct _IOSocket *iosock) { free(iosock); } -static void iosocket_activate(struct _IOSocket *iosock) { +void iosocket_activate(struct _IOSocket *iosock) { if((iosock->socket_flags & IOSOCKETFLAG_ACTIVE)) return; iosock->socket_flags |= IOSOCKETFLAG_ACTIVE; engine->add(iosock); } -static void iosocket_deactivate(struct _IOSocket *iosock) { +void iosocket_deactivate(struct _IOSocket *iosock) { if(!(iosock->socket_flags & IOSOCKETFLAG_ACTIVE)) return; iosock->socket_flags &= ~IOSOCKETFLAG_ACTIVE; engine->remove(iosock); } +void iosocket_update(struct _IOSocket *iosock) { + if(!(iosock->socket_flags & IOSOCKETFLAG_ACTIVE)) + return; + engine->update(iosock); +} + static void iosocket_increase_buffer(struct IOSocketBuffer *iobuf, size_t required) { if(iobuf->buflen >= required) return; char *new_buf; @@ -546,7 +551,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)); @@ -555,7 +560,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)); @@ -586,6 +591,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); @@ -748,7 +754,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; } @@ -804,7 +810,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; @@ -854,6 +860,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) @@ -883,7 +911,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; @@ -960,15 +993,22 @@ 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; + 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; @@ -982,6 +1022,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) { @@ -1030,6 +1071,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) { @@ -1056,7 +1099,7 @@ void iosocket_events_callback(struct _IOSocket *iosock, int readable, int writea iosocket_close(iosocket); } else if((iosock->socket_flags & IOSOCKETFLAG_PARENT_DNSENGINE)) { - //TODO: IODNS callback + iodns_socket_callback(iosock, readable, writeable); } }