Fix typos in comments and strings to reduce future slumming for credit.
[ircu2.10.12-pk.git] / ircd / os_generic.c
index 203c107ab3d2e0ec8a4d2f3825476434ccc030cf..d2f73b6363d4385d3c0dc2cef7d247d2571481f6 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* @file
+/** @file
  * @brief Implementation of OS-dependent operations.
  * @version $Id$
  */
 #include "config.h"
 
-#define _XOPEN_SOURCE  500 /**< make limits.h #define IOV_MAX */
+#define _XOPEN_SOURCE  600 /**< make limits.h #define IOV_MAX */
 #define __EXTENSIONS__  1   /**< make Solaris netinet/in.h know IPv6 */
 
 #include "ircd_osdep.h"
 #include "msgq.h"
+#include "ircd_log.h"
 #include "res.h"
 #include "s_bsd.h"
 #include "sys.h"
@@ -37,7 +38,7 @@
  * Solaris requires sys/time.h before struct rusage (indirectly) in
  * netinet/in.h.
  */
-#include <assert.h>
+/* #include <assert.h> -- Now using assert in ircd_log.h */
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
@@ -97,19 +98,27 @@ void sockaddr_to_irc(const struct sockaddr_in6 *v6, struct irc_sockaddr *irc)
 /** Convert IRC socket address to native format.
  * @param[out] v6 Native socket address.
  * @param[in] irc IRC socket address.
- * @param[in] persist If non-zero, and \a irc is an IPv4 address,
- * create an AF_INET size address.
+ * @param[in] compat_fd If non-negative, an FD specifying address family.
  * @return Length of address written to \a v6.
  */
-int sockaddr_from_irc(struct sockaddr_in6 *v6, const struct irc_sockaddr *irc, int persist)
+int sockaddr_from_irc(struct sockaddr_in6 *v6, const struct irc_sockaddr *irc, int compat_fd)
 {
+    struct sockaddr_in6 sin6;
+    socklen_t slen;
+    int family;
+
+    assert(irc != 0);
+    slen = sizeof(sin6);
+    if ((0 <= compat_fd)
+        && (0 == getsockname(compat_fd, (struct sockaddr*)&sin6, &slen)))
+        family = sin6.sin6_family;
+    else if ((irc == &VirtualHost_v4) || irc_in_addr_is_ipv4(&irc->addr))
+        family = AF_INET;
+    else
+        family = AF_INET6;
+
     memset(v6, 0, sizeof(*v6));
-    if (!irc) {
-        memset(v6, 0, sizeof(v6));
-        v6->sin6_family = AF_INET6;
-        return sizeof(*v6);
-    }
-    else if (persist && irc_in_addr_is_ipv4(&irc->addr)) {
+    if (family == AF_INET) {
         struct sockaddr_in *v4 = (struct sockaddr_in*)v6;
         v4->sin_family = AF_INET;
         memcpy(&v4->sin_addr, &irc->addr.in6_16[6], sizeof(v4->sin_addr));
@@ -136,8 +145,9 @@ void sockaddr_to_irc(const struct sockaddr_in *v4, struct irc_sockaddr *irc)
     irc->port = ntohs(v4->sin_port);
 }
 
-int sockaddr_from_irc(struct sockaddr_in *v4, const struct irc_sockaddr *irc, int persist)
+int sockaddr_from_irc(struct sockaddr_in *v4, const struct irc_sockaddr *irc, int compat_fd)
 {
+    assert(irc != 0);
     v4->sin_family = AF_INET;
     if (irc) {
         assert(!irc->addr.in6_16[0] && !irc->addr.in6_16[1] && !irc->addr.in6_16[2] && !irc->addr.in6_16[3] && !irc->addr.in6_16[4] && (!irc->addr.in6_16[5] || irc->addr.in6_16[5] == 0xffff));
@@ -146,15 +156,15 @@ int sockaddr_from_irc(struct sockaddr_in *v4, const struct irc_sockaddr *irc, in
     } else{
         memset(&v4, 0, sizeof(v4));
     }
-    (void)persist;
+    (void)compat_fd;
     return sizeof(*v4);
 }
 
 #endif
 
 /*
- * This is part of the STATS replies. There is no offical numeric for this
- * since this isnt an official command, in much the same way as HASH isnt.
+ * This is part of the STATS replies. There is no official numeric for this
+ * since this isn't an official command, in much the same way as HASH isn't.
  * It is also possible that some systems wont support this call or have
  * different field names for "struct rusage".
  * -avalon
@@ -497,7 +507,8 @@ IOResult os_sendto_nonb(int fd, const char* buf, unsigned int length,
     *count_out = 0;
   errno = 0;
 
-  size = sockaddr_from_irc(&addr, peer, 1);
+  size = sockaddr_from_irc(&addr, peer, fd);
+  assert((addr.sn_family == AF_INET) == irc_in_addr_is_ipv4(&peer->addr));
   if (-1 < (res = sendto(fd, buf, length, flags, (struct sockaddr*)&addr, size))) {
     if (count_out)
       *count_out = (unsigned) res;
@@ -599,7 +610,8 @@ int os_socket(const struct irc_sockaddr* local, int type, const char* port_name)
   struct sockaddr_native addr;
   int size, fd;
 
-  size = sockaddr_from_irc(&addr, local, 1);
+  assert(local != 0);
+  size = sockaddr_from_irc(&addr, local, -1);
   fd = socket(addr.sn_family, type, 0);
   if (fd < 0) {
     report_error(SOCKET_ERROR_MSG, port_name, errno);
@@ -660,7 +672,7 @@ IOResult os_connect_nonb(int fd, const struct irc_sockaddr* sin)
   struct sockaddr_native addr;
   int size;
 
-  size = sockaddr_from_irc(&addr, sin, 1);
+  size = sockaddr_from_irc(&addr, sin, fd);
   if (connect(fd, (struct sockaddr*) &addr, size))
     return (errno == EINPROGRESS) ? IO_BLOCKED : IO_FAILURE;
   return IO_SUCCESS;