@@ -204,15 +204,29 @@ { of_resolver_result_t **results = of_resolve_host(host, port, SOCK_DGRAM); assert(results[0]->addressLength <= - (socklen_t)sizeof(address->address)); + (socklen_t)sizeof(address->sockaddr)); - memcpy(&address->address, results[0]->address, + memcpy(&address->sockaddr, results[0]->address, results[0]->addressLength); address->length = results[0]->addressLength; + + switch (results[0]->address->sa_family) { + case AF_INET: + address->family = OF_SOCKET_ADDRESS_FAMILY_IPV4; + break; +#ifdef OF_HAVE_IPV6 + case AF_INET6: + address->family = OF_SOCKET_ADDRESS_FAMILY_IPV6; + break; +#endif + default: + address->family = OF_SOCKET_ADDRESS_FAMILY_UNKNOWN; + break; + } of_resolver_free(results); } #ifdef OF_HAVE_THREADS @@ -316,20 +330,11 @@ - (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port { of_resolver_result_t **results; -#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) - union { - struct sockaddr_storage storage; - struct sockaddr_in in; -# ifdef OF_HAVE_IPV6 - struct sockaddr_in6 in6; -# endif - } addr; - socklen_t addrLen; -#endif + of_socket_address_t address; results = of_resolve_host(host, port, SOCK_DGRAM); @try { #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) int flags; @@ -423,13 +428,13 @@ if (port > 0) return port; #if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) - addrLen = (socklen_t)sizeof(addr.storage); - if (of_getsockname(_socket, (struct sockaddr *)&addr.storage, - &addrLen) != 0) { + address.length = (socklen_t)sizeof(address.sockaddr); + if (of_getsockname(_socket, &address.sockaddr.sockaddr, + &address.length) != 0) { int errNo = of_socket_errno(); closesocket(_socket); _socket = INVALID_SOCKET; @@ -437,15 +442,15 @@ port: port socket: self errNo: errNo]; } - if (addr.storage.ss_family == AF_INET) - return OF_BSWAP16_IF_LE(addr.in.sin_port); + if (address.sockaddr.sockaddr.sa_family == AF_INET) + return OF_BSWAP16_IF_LE(address.sockaddr.in.sin_port); # ifdef OF_HAVE_IPV6 - if (addr.storage.ss_family == AF_INET6) - return OF_BSWAP16_IF_LE(addr.in6.sin6_port); + if (address.sockaddr.sockaddr.sa_family == AF_INET6) + return OF_BSWAP16_IF_LE(address.sockaddr.in6.sin6_port); # endif #endif closesocket(_socket); _socket = INVALID_SOCKET; @@ -462,30 +467,44 @@ ssize_t ret; if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; - sender->length = (socklen_t)sizeof(sender->address); + sender->length = (socklen_t)sizeof(sender->sockaddr); #ifndef OF_WINDOWS if ((ret = recvfrom(_socket, buffer, length, 0, - (struct sockaddr *)&sender->address, &sender->length)) < 0) + &sender->sockaddr.sockaddr, &sender->length)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: of_socket_errno()]; #else if (length > INT_MAX) @throw [OFOutOfRangeException exception]; if ((ret = recvfrom(_socket, buffer, (int)length, 0, - (struct sockaddr *)&sender->address, &sender->length)) < 0) + &sender->sockaddr.sockaddr, &sender->length)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: of_socket_errno()]; #endif + + switch (sender->sockaddr.sockaddr.sa_family) { + case AF_INET: + sender->family = OF_SOCKET_ADDRESS_FAMILY_IPV4; + break; +#ifdef OF_HAVE_IPV6 + case AF_INET6: + sender->family = OF_SOCKET_ADDRESS_FAMILY_IPV6; + break; +#endif + default: + sender->family = OF_SOCKET_ADDRESS_FAMILY_UNKNOWN; + break; + } return ret; } - (void)asyncReceiveIntoBuffer: (void *)buffer @@ -526,11 +545,11 @@ if (length > SSIZE_MAX) @throw [OFOutOfRangeException exception]; if ((bytesWritten = sendto(_socket, buffer, length, 0, - (struct sockaddr *)&receiver->address, receiver->length)) < 0) + &receiver->sockaddr.sockaddr, receiver->length)) < 0) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: 0 errNo: of_socket_errno()]; @@ -539,12 +558,11 @@ if (length > INT_MAX) @throw [OFOutOfRangeException exception]; if ((bytesWritten = sendto(_socket, buffer, (int)length, 0, - (struct sockaddr *)&receiver->address, - receiver->length)) < 0) + &receiver->sockaddr.sockaddr, receiver->length)) < 0) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: 0 errNo: of_socket_errno()];