X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fnetwork.c;h=101e794d07c892827182455620e7d30dec5f2b88;hb=555214089c7045298f23fea9e060ea931804e75f;hp=d889fa94bde1cb022464cd8ef9a1ad3a986d409f;hpb=45617d6ab679a5be3bc6fde49d9fac88fca1ad86;p=oweals%2Fgnunet.git diff --git a/src/util/network.c b/src/util/network.c index d889fa94b..101e794d0 100644 --- a/src/util/network.c +++ b/src/util/network.c @@ -38,7 +38,13 @@ struct GNUNET_NETWORK_Handle { +#ifndef MINGW int fd; + +#else + SOCKET fd; +#endif + }; @@ -57,7 +63,7 @@ struct GNUNET_NETWORK_FDSet #ifdef WINDOWS /** - * Linked list of handles + * Linked list of handles */ struct GNUNET_CONTAINER_SList *handles; #endif @@ -128,11 +134,16 @@ static int socket_set_inheritable (const struct GNUNET_NETWORK_Handle *h) { int i; - i = fcntl (h->fd, F_GETFD); + + i = fcntl (h->fd, F_GETFD); + if (i < 0) + return GNUNET_SYSERR; if (i == (i | FD_CLOEXEC)) return GNUNET_OK; - return (fcntl (h->fd, F_SETFD, i | FD_CLOEXEC) == 0) - ? GNUNET_OK : GNUNET_SYSERR; + i |= FD_CLOEXEC; + if (fcntl (h->fd, F_SETFD, i) < 0) + return GNUNET_SYSERR; + return GNUNET_OK; } #endif @@ -185,6 +196,7 @@ GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Handle *desc, socklen_t * address_len) { struct GNUNET_NETWORK_Handle *ret; + ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle)); ret->fd = accept (desc->fd, address, address_len); if (ret->fd == INVALID_SOCKET) @@ -222,7 +234,10 @@ GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Handle *desc, #ifdef DARWIN socket_set_nosigpipe (ret); #endif - socket_set_nodelay (ret); +#ifdef AF_UNIX + if (address->sa_family != AF_UNIX) +#endif + socket_set_nodelay (ret); return ret; } @@ -245,6 +260,17 @@ GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc, #ifdef MINGW if (SOCKET_ERROR == ret) SetErrnoFromWinsockError (WSAGetLastError ()); +#else +#ifndef LINUX + if ( (ret == 0) && (address->sa_family == AF_UNIX)) + { + const struct sockaddr_un *un = (const struct sockaddr_un*) address; + if (0 != unlink (un->sun_path)) + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, + "unlink", + un->sun_path); + } +#endif #endif return ret == 0 ? GNUNET_OK : GNUNET_SYSERR; } @@ -259,7 +285,6 @@ int GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Handle *desc) { int ret; - int eno; #ifdef MINGW ret = closesocket (desc->fd); @@ -267,13 +292,34 @@ GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Handle *desc) #else ret = close (desc->fd); #endif - eno = errno; GNUNET_free (desc); - errno = eno; return (ret == 0) ? GNUNET_OK : GNUNET_SYSERR; } +/** + * Box a native socket (and check that it is a socket). + * + * @param fd socket to box + * @return NULL on error (including not supported on target platform) + */ +struct GNUNET_NETWORK_Handle * +GNUNET_NETWORK_socket_box_native (int fd) +{ +#if MINGW + return NULL; +#else + struct GNUNET_NETWORK_Handle *ret; + + if (fcntl (fd, F_GETFD) < 0) + return NULL; /* invalid FD */ + ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle)); + ret->fd = fd; + return ret; +#endif +} + + /** * Connect a socket * @param desc socket @@ -354,6 +400,64 @@ GNUNET_NETWORK_socket_listen (const struct GNUNET_NETWORK_Handle *desc, } +/** + * How much data is available to be read on this descriptor? + * + * Returns GNUNET_NO if no data is available, or on error! + * @param desc socket + */ +ssize_t +GNUNET_NETWORK_socket_recvfrom_amount (const struct GNUNET_NETWORK_Handle + *desc) +{ + int error; + int pending; + + /* How much is there to be read? */ +#ifndef WINDOWS + error = ioctl (desc->fd, FIONREAD, &pending); + if (error == 0) +#else + error = ioctlsocket (desc->fd, FIONREAD, &pending); + if (error != SOCKET_ERROR) +#endif + return pending; + else + return GNUNET_NO; +} + +/** + * Read data from a connected socket (always non-blocking). + * @param desc socket + * @param buffer buffer + * @param length length of buffer + * @param src_addr either the source to recv from, or all zeroes + * to be filled in by recvfrom + * @param addrlen length of the addr + */ +ssize_t +GNUNET_NETWORK_socket_recvfrom (const struct GNUNET_NETWORK_Handle * desc, + void *buffer, size_t length, + struct sockaddr * src_addr, + socklen_t * addrlen) +{ + int ret; + int flags; + flags = 0; + +#ifdef MSG_DONTWAIT + flags |= MSG_DONTWAIT; + +#endif + ret = recvfrom (desc->fd, buffer, length, flags, src_addr, addrlen); +#ifdef MINGW + if (SOCKET_ERROR == ret) + SetErrnoFromWinsockError (WSAGetLastError ()); +#endif + return ret; +} + + /** * Read data from a connected socket (always non-blocking). * @param desc socket @@ -370,15 +474,12 @@ GNUNET_NETWORK_socket_recv (const struct GNUNET_NETWORK_Handle * desc, #ifdef MSG_DONTWAIT flags |= MSG_DONTWAIT; - -#endif /* */ +#endif ret = recv (desc->fd, buffer, length, flags); - #ifdef MINGW if (SOCKET_ERROR == ret) SetErrnoFromWinsockError (WSAGetLastError ()); - -#endif /* */ +#endif return ret; } @@ -531,7 +632,11 @@ GNUNET_NETWORK_socket_create (int domain, int type, int protocol) #ifdef DARWIN socket_set_nosigpipe (ret); #endif - if (type == SOCK_STREAM) + if ( (type == SOCK_STREAM) +#ifdef AF_UNIX + && (domain != AF_UNIX) +#endif + ) socket_set_nodelay (ret); return ret; } @@ -643,6 +748,12 @@ GNUNET_NETWORK_fdset_copy (struct GNUNET_NETWORK_FDSet *to, #endif } +int +GNUNET_NETWORK_get_fd (struct GNUNET_NETWORK_Handle *desc) +{ + return desc->fd; +} + /** * Copy a native fd set * @@ -658,6 +769,38 @@ GNUNET_NETWORK_fdset_copy_native (struct GNUNET_NETWORK_FDSet *to, to->nsds = nfds; } + +/** + * Set a native fd in a set + * + * @param to destination + * @param nfd native FD to set + */ +void GNUNET_NETWORK_fdset_set_native (struct GNUNET_NETWORK_FDSet *to, + int nfd) +{ + FD_SET (nfd, &to->sds); + to->nsds = GNUNET_MAX (nfd + 1, to->nsds); +} + + +/** + * Test native fd in a set + * + * @param to set to test, NULL for empty set + * @param nfd native FD to test, or -1 for none + * @return GNUNET_YES if FD is set in the set + */ +int +GNUNET_NETWORK_fdset_test_native (const struct GNUNET_NETWORK_FDSet *to, + int nfd) +{ + if ( (nfd == -1) || (to == NULL) ) + return GNUNET_NO; + return FD_ISSET (nfd, &to->sds) ? GNUNET_YES : GNUNET_NO; +} + + /** * Add a file handle to the fd set * @param fds fd set @@ -671,7 +814,9 @@ GNUNET_NETWORK_fdset_handle_set (struct GNUNET_NETWORK_FDSet *fds, #ifdef MINGW HANDLE hw; GNUNET_DISK_internal_file_handle_ (h, &hw, sizeof (HANDLE)); - GNUNET_CONTAINER_slist_add (fds->handles, GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT, &hw, sizeof (HANDLE)); + GNUNET_CONTAINER_slist_add (fds->handles, + GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT, + &hw, sizeof (HANDLE)); #else int fd; @@ -723,20 +868,23 @@ GNUNET_NETWORK_fdset_overlap (const struct GNUNET_NETWORK_FDSet *fds1, return GNUNET_YES; #ifdef MINGW { - struct GNUNET_CONTAINER_SList_Iterator *it; + struct GNUNET_CONTAINER_SList_Iterator *it; - for(it = GNUNET_CONTAINER_slist_begin (fds1->handles); GNUNET_CONTAINER_slist_end (it) != GNUNET_YES; GNUNET_CONTAINER_slist_next (it)) - { - HANDLE *h; - - h = GNUNET_CONTAINER_slist_get (it, NULL); - if (GNUNET_CONTAINER_slist_contains (fds2->handles, h, sizeof (HANDLE))) - { - GNUNET_CONTAINER_slist_iter_destroy (it); - return GNUNET_YES; - } - } - GNUNET_CONTAINER_slist_iter_destroy (it); + for (it = GNUNET_CONTAINER_slist_begin (fds1->handles); + GNUNET_CONTAINER_slist_end (it) != GNUNET_YES; + GNUNET_CONTAINER_slist_next (it)) + { + HANDLE *h; + + h = GNUNET_CONTAINER_slist_get (it, NULL); + if (GNUNET_CONTAINER_slist_contains + (fds2->handles, h, sizeof (HANDLE))) + { + GNUNET_CONTAINER_slist_iter_destroy (it); + return GNUNET_YES; + } + } + GNUNET_CONTAINER_slist_iter_destroy (it); } #endif return GNUNET_NO; @@ -845,7 +993,8 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, DWORD limit; fd_set sock_read, sock_write, sock_except; fd_set aread, awrite, aexcept; - struct GNUNET_CONTAINER_SList *handles_read, *handles_write, *handles_except; + struct GNUNET_CONTAINER_SList *handles_read, *handles_write, + *handles_except; int i; struct timeval tvslice; @@ -952,8 +1101,8 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, { GNUNET_CONTAINER_slist_add (handles_read, - GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT, &h, - sizeof (HANDLE)); + GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT, + &h, sizeof (HANDLE)); retcode++; } } @@ -977,8 +1126,8 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, { GNUNET_CONTAINER_slist_add (handles_except, - GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT, &h, - sizeof (HANDLE)); + GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT, + &h, sizeof (HANDLE)); retcode++; } } @@ -1027,19 +1176,15 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, while (retcode == 0 && (ms_total == INFINITE || GetTickCount () < limit)); if (retcode != -1) - { if (rfds) - { GNUNET_NETWORK_fdset_zero (rfds); GNUNET_NETWORK_fdset_copy_native (rfds, &aread, retcode); GNUNET_CONTAINER_slist_clear (rfds->handles); GNUNET_CONTAINER_slist_append (rfds->handles, handles_read); - } if (wfds) - { GNUNET_NETWORK_fdset_zero (wfds); GNUNET_NETWORK_fdset_copy_native (wfds, &awrite, retcode); @@ -1047,7 +1192,6 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, GNUNET_CONTAINER_slist_append (wfds->handles, handles_write); } if (efds) - { GNUNET_NETWORK_fdset_zero (efds); GNUNET_NETWORK_fdset_copy_native (efds, &aexcept, retcode);