*/
#include "config.h"
-#define _XOPEN_SOURCE 500 /**< make limits.h #define IOV_MAX */
-#define __EXTENSIONS__ 1 /**< make Solaris netinet/in.h know IPv6 */
+#ifdef IRCU_SOLARIS
+/* Solaris requires C99 support for SUSv3, but C99 support breaks other
+ * parts of the build. So fall back to SUSv2, but request IPv6 support
+ * by defining __EXTENSIONS__.
+ */
+#define _XOPEN_SOURCE 500
+#define __EXTENSIONS__ 1
+#else
+/* FreeBSD 6.0 requires SUSv3 to support IPv6. Apparently some other
+ * OS requires SUSv3 to define IOV_MAX, but its identity is lost for
+ * the time being.
+ */
+#define _XOPEN_SOURCE 600
+#endif
#include "ircd_osdep.h"
#include "msgq.h"
+#include "ircd_log.h"
#include "res.h"
#include "s_bsd.h"
#include "sys.h"
* 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>
#define getrusage(a,b) syscall(SYS_GETRUSAGE, a, b)
#endif
+
+static void sockaddr_in_to_irc(const struct sockaddr_in *v4,
+ struct irc_sockaddr *irc)
+{
+ memset(&irc->addr, 0, 5*sizeof(int16_t));
+ irc->addr.in6_16[5] = 0xffff;
+ memcpy(&irc->addr.in6_16[6], &v4->sin_addr, sizeof(v4->sin_addr));
+ irc->port = ntohs(v4->sin_port);
+}
+
+
#ifdef IPV6
/** Native socket address type. */
#define sockaddr_native sockaddr_in6
irc->port = ntohs(v6->sin6_port);
}
else if (v6->sin6_family == AF_INET) {
- const struct sockaddr_in *v4 = (const struct sockaddr_in*)v6;
- memset(&irc->addr, 0, 5*sizeof(int16_t));
- irc->addr.in6_16[5] = 0xffff;
- memcpy(&irc->addr.in6_16[6], &v4->sin_addr, sizeof(v4->sin_addr));
- irc->port = ntohs(v4->sin_port);
+ sockaddr_in_to_irc((struct sockaddr_in *)v6, irc);
}
else assert(0 && "Unhandled native address family");
}
socklen_t slen;
int family;
+ assert(irc != 0);
slen = sizeof(sin6);
- if ((0 <= compat_fd) && (0 == getsockname(compat_fd, (struct sockaddr*)&sin6, &slen)))
+ if ((0 <= compat_fd)
+ && (0 == getsockname(compat_fd, (struct sockaddr*)&sin6, &slen)))
family = sin6.sin6_family;
- else if (irc_in_addr_is_ipv4(&VirtualHost.addr))
+ 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 ((family == AF_INET) && 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));
#else
#define sockaddr_native sockaddr_in
#define sn_family sin_family
-
-void sockaddr_to_irc(const struct sockaddr_in *v4, struct irc_sockaddr *irc)
-{
- assert(v4->sin_family == AF_INET);
- memset(&irc->addr, 0, 6*sizeof(irc->addr.in6_16[0]));
- memcpy(&irc->addr.in6_16[6], &v4->sin_addr, sizeof(v4->sin_addr));
- irc->port = ntohs(v4->sin_port);
-}
+#define sockaddr_to_irc sockaddr_in_to_irc
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));
#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.
- * It is also possible that some systems wont support this call or have
- * different field names for "struct rusage".
- * -avalon
- */
-/** Send resource usage information to a client.
+#ifdef DEBUGMODE
+/** Send resource usage information to an enumerator function.
* @param[in] cptr Client requesting information.
* @param[in] uptime Wall time in seconds since the server started.
* @param[in] enumerator Function to call to send a line to \a cptr.
#endif /* HAVE_GETRUSAGE */
return 1;
}
+#endif
/** Look up the most recent socket error for a socket file descriptor.
* @param[in] fd File descriptor to check.
errno = 0;
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;
struct sockaddr_native addr;
int size, fd;
+ assert(local != 0);
size = sockaddr_from_irc(&addr, local, -1);
fd = socket(addr.sn_family, type, 0);
if (fd < 0) {