X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2FIOHandler%2FIOSockets.c;h=7c3c50a8f7e8b8770afd72a77f12acaed628d27d;hb=0f7daad2c06bc06a9d66fc5d6b6e65585b767866;hp=abae08fdb0c04f57ed2795421589c7c3a9497262;hpb=41292e20c03e930e8fb3a03f1607fd71b4c1c6bb;p=NextIRCd.git diff --git a/src/IOHandler/IOSockets.c b/src/IOHandler/IOSockets.c index abae08f..7c3c50a 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 @@ -44,7 +47,7 @@ #include #ifndef EWOULDBLOCK -#define EWOULDBLOCK EAGAIN +#define EWOULDBLOCK WSAEWOULDBLOCK #endif struct _IOSocket *iosocket_first = NULL; @@ -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(); @@ -483,6 +486,29 @@ static void iosocket_prepare_fd(int sockfd) { #endif } +static void iosocket_update_parent(struct _IOSocket *iosock) { + if((iosock->socket_flags & IOSOCKETFLAG_PARENT_PUBLIC)) { + struct IOSocket *iosocket = iosock->parent; + iosocket->ipv6 = ((iosock->socket_flags & IOSOCKETFLAG_IPV6SOCKET) ? 1 : 0); + if(!(iosock->socket_flags & IOSOCKETFLAG_LISTENING)) + iosocket->remoteaddr = &iosock->dest.addr; + iosocket->localaddr = &iosock->bind.addr; + if(iosock->bind.addr.addresslen && (iosock->socket_flags & IOSOCKETFLAG_DYNAMIC_BIND)) { + free(iosock->bind.addr.address); + iosock->bind.addr.addresslen = 0; + } + if(!iosock->bind.addr.addresslen) { + iosock->socket_flags |= IOSOCKETFLAG_DYNAMIC_BIND; + if(iosocket->ipv6) + iosock->bind.addr.addresslen = sizeof(struct sockaddr_in6); + else + iosock->bind.addr.addresslen = sizeof(struct sockaddr_in); + iosock->bind.addr.address = malloc(iosock->bind.addr.addresslen); + getsockname(iosock->fd, (struct sockaddr *)iosock->bind.addr.address, (socklen_t *)&iosock->bind.addr.addresslen); + } + } +} + static void iosocket_connect_finish(struct _IOSocket *iosock) { int sockfd; if((iosock->socket_flags & IOSOCKETFLAG_IPV6SOCKET)) @@ -502,7 +528,7 @@ static void iosocket_connect_finish(struct _IOSocket *iosock) { ip6->sin6_family = AF_INET6; ip6->sin6_port = htons(iosock->port); - if(iosock->bind.addr.addresslen) { + if(iosock->bind.addr.addresslen && !(iosock->socket_flags & IOSOCKETFLAG_DYNAMIC_BIND)) { struct sockaddr_in6 *ip6bind = (void*) iosock->bind.addr.address; ip6bind->sin6_family = AF_INET6; ip6bind->sin6_port = htons(0); @@ -514,7 +540,7 @@ static void iosocket_connect_finish(struct _IOSocket *iosock) { ip4->sin_family = AF_INET; ip4->sin_port = htons(iosock->port); - if(iosock->bind.addr.addresslen) { + if(iosock->bind.addr.addresslen && !(iosock->socket_flags & IOSOCKETFLAG_DYNAMIC_BIND)) { struct sockaddr_in *ip4bind = (void*) iosock->bind.addr.address; ip4bind->sin_family = AF_INET; ip4bind->sin_port = htons(0); @@ -572,6 +598,7 @@ static void iosocket_listen_finish(struct _IOSocket *iosock) { listen(sockfd, 1); iosock->fd = sockfd; + iosocket_update_parent(iosock); iosocket_activate(iosock); } @@ -633,8 +660,12 @@ 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_update_parent(new_iosock); iosocket_activate(new_iosock); return new_iosock; } @@ -794,6 +825,32 @@ void iosocket_close(struct IOSocket *iosocket) { iogc_add(iosocket); } +struct IODNSAddress *iosocket_get_remote_addr(struct IOSocket *iosocket) { + struct _IOSocket *iosock = iosocket->iosocket; + if(iosock == NULL) { + iolog_trigger(IOLOG_WARNING, "called iosocket_get_remote_addr for destroyed IOSocket in %s:%d", __FILE__, __LINE__); + return NULL; + } + 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) { + struct _IOSocket *iosock = iosocket->iosocket; + if(iosock == NULL) { + iolog_trigger(IOLOG_WARNING, "called iosocket_get_local_addr for destroyed IOSocket in %s:%d", __FILE__, __LINE__); + return NULL; + } + 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; @@ -982,6 +1039,8 @@ void iosocket_events_callback(struct _IOSocket *iosock, int readable, int writea callback_event.type = IOSOCKETEVENT_CONNECTED; engine->update(iosock); + iosocket_update_parent(iosock); + //initialize readbuf iosocket_increase_buffer(&iosock->readbuf, 1024); } @@ -996,12 +1055,16 @@ void iosocket_events_callback(struct _IOSocket *iosock, int readable, int writea iosocketevents_callback_retry_read: if((readable && ssl_rehandshake == 0) || ssl_rehandshake == 1) { int bytes; - if(iosock->readbuf.buflen - iosock->readbuf.bufpos >= 128) { + 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)) @@ -1009,14 +1072,20 @@ void iosocket_events_callback(struct _IOSocket *iosock, int readable, int writea else bytes = recv(iosock->fd, iosock->readbuf.buffer + iosock->readbuf.bufpos, iosock->readbuf.buflen - iosock->readbuf.bufpos, 0); - if(bytes <= 0) { + if(bytes <= 0) { + int errcode; + #ifdef WIN32 + errcode = WSAGetLastError(); + #else + errcode = errno; + #endif if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_READHS)) == (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_READHS)) { ssl_rehandshake = 1; - } else if (errno != EAGAIN || errno != EWOULDBLOCK) { + } else if (errcode != EAGAIN && errcode != EWOULDBLOCK) { iosock->socket_flags |= IOSOCKETFLAG_DEAD; callback_event.type = IOSOCKETEVENT_CLOSED; - callback_event.data.errid = errno; + callback_event.data.errid = errcode; } } else { int i;