]> git.ipfire.org Git - thirdparty/HylaFAX.git/commitdiff
Socket fixes for BSD 4.4 sockets
authorAidan Van Dyk <aidan@ifax.com>
Sat, 23 May 2009 12:22:02 +0000 (12:22 +0000)
committerPatrice Fournier <pfournier@ifax.com>
Fri, 31 Jul 2009 16:09:01 +0000 (12:09 -0400)
Giovanni Bechis reported things not working on OpenBSD, which uses the BSD
4.4 sockaddr struct which doesn't have sa_family as the first member.  So
we can't rely on a family being the first member of our union either.
(cherry picked from commit 9695174b15fa8839ec7203c4c6def1a1b87e5f5d)

hfaxd/InetFaxServer.c++
hfaxd/SuperServer.c++
libhylafax/InetTransport.c++
libhylafax/Socket.h

index 1a2635493280a3b76b2dfd987bce38190d73f57a..8ae87d40fbc182c784165f6006e9ababa0888888 100644 (file)
@@ -87,11 +87,11 @@ InetSuperServer::startServer(void)
         * Somethings broken here, let's pick some conservative defaults
         */
        memset(&addr, 0, sizeof(addr));
-       addr.family = AF_INET;
+       Socket::family(addr) = AF_INET;
        addr.in.sin_port = htons(FAX_DEFPORT);
     }
 
-    int s = socket(addr.family, SOCK_STREAM, 0);
+    int s = socket(Socket::family(addr), SOCK_STREAM, 0);
     if (s >= 0) {
        int on = 1;
        if (Socket::setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) >= 0) {
@@ -119,7 +119,7 @@ InetFaxServer::InetFaxServer()
     swaitint = 5;                      // interval between retries
 
     memset(&data_dest, 0, sizeof (data_dest));
-    data_dest.family = AF_INET6;       // We'll allow AF_INET6 by default.
+    Socket::family(data_dest) = AF_INET6;      // We'll allow AF_INET6 by default.
 
     hostent* hp = Socket::gethostbyname(hostname);
 
@@ -211,7 +211,7 @@ logDebug("checkHostIdentity(\"%s\")", name);
     if (getaddrinfo(name, NULL, &hints, &ai) == 0) {
        for (struct addrinfo *aip = ai; aip != NULL; aip = aip->ai_next) {
            Socket::Address *addr = (Socket::Address*)aip->ai_addr;
-           if (aip->ai_family != peer_addr.family)
+           if (aip->ai_family != Socket::family(peer_addr))
                continue;
            if ( (aip->ai_family == AF_INET6 &&
                     memcmp(&addr->in6.sin6_addr, &peer_addr.in6.sin6_addr, sizeof(struct in6_addr)) ==0)
@@ -287,7 +287,7 @@ InetFaxServer::setupNetwork(int fd)
 
     char hostbuf[128];
 
-    remoteaddr = inet_ntop(peer_addr.family, Socket::addr(peer_addr), hostbuf, sizeof(hostbuf));
+    remoteaddr = inet_ntop(Socket::family(peer_addr), Socket::addr(peer_addr), hostbuf, sizeof(hostbuf));
 
     getnameinfo((struct sockaddr*)&peer_addr, Socket::socklen(peer_addr),
                    hostbuf, sizeof(hostbuf), NULL, 0, 0);
@@ -378,8 +378,8 @@ InetFaxServer::passiveCmd(void)
 {
     if (tokenBody[0] == 'E') {
        pasv_addr = ctrl_addr;
-       logDebug("Extended passive requested for family %d", pasv_addr.family);
-       pdata = socket(pasv_addr.family, SOCK_STREAM, 0);
+       logDebug("Extended passive requested for family %d", Socket::family(pasv_addr));
+       pdata = socket(Socket::family(pasv_addr), SOCK_STREAM, 0);
        if (pdata >= 0) {
            Socket::port(pasv_addr) = 0;
            if (!setupPassiveDataSocket(pdata, pasv_addr))
@@ -392,7 +392,7 @@ InetFaxServer::passiveCmd(void)
            perror_reply(425, "Cannot setup extended passive connection", errno);
        return;
     }
-    if (ctrl_addr.family != AF_INET) {
+    if (Socket::family(ctrl_addr) != AF_INET) {
        reply(500, "Cannot use PASV with IPv6 connections");
        return;
     }
@@ -444,7 +444,7 @@ InetFaxServer::getDataSocket(const char* mode)
 {
     if (data >= 0)
         return (fdopen(data, mode));
-    int s = socket(data_dest.family, SOCK_STREAM, 0);
+    int s = socket(Socket::family(data_dest), SOCK_STREAM, 0);
     if (s < 0)
         goto bad;
     { int on = 1;
index ef0a9364726b2963a961ce445f9c96343b22f09e..983fdbc52cc484b9ff791c4b7f0cdba3b4e55a2e 100644 (file)
@@ -68,7 +68,7 @@ SuperServer::inputReady(int fd)
        _exit(-1);
     }
 #ifdef IPV6_ADDRFORM
-    if (addr.family == AF_INET6) {
+    if (Socket::family(addr) == AF_INET6) {
        struct in6_addr& a = addr.in6.sin6_addr;
        if ( (a.s6_addr32[0] == 0 && a.s6_addr32[1] == 0 && a.s6_addr32[2] == htonl(0xFFFF))  ||
             (a.s6_addr32[0] == 0 && a.s6_addr32[1] == 0 && a.s6_addr32[2] == 0 && ntohl(a.s6_addr32[3]) > 1) ) {
index 445a02ba733ab4ce8377706b37b578e421fa3121..8adab065fdf9fa828b90914f8128f6061142863b 100644 (file)
@@ -120,11 +120,11 @@ InetTransport::callServer(fxStr& emsg)
     {
        Socket::Address *addr = (Socket::Address*)aip->ai_addr;
        char buf[256];                          // For inet_ntop use
-       fxAssert(aip->ai_family == addr->family, "addrinfo ai_family doesn't match in_addr->ai_info");
+       fxAssert(aip->ai_family == Socket::family(*addr), "addrinfo ai_family doesn't match in_addr->ai_info");
        if (client.getVerbose())
            client.traceServer(NLS::TEXT("Trying %s [%d] (%s) at port %u..."),
-                   (const char*)client.getHost(), addr->family,
-                   inet_ntop(addr->family, Socket::addr(*addr), buf, sizeof(buf)),
+                   (const char*)client.getHost(), Socket::family(*addr),
+                   inet_ntop(Socket::family(*addr), Socket::addr(*addr), buf, sizeof(buf)),
                    ntohs(Socket::port(*addr)));
        int fd = socket (aip->ai_family, aip->ai_socktype, aip->ai_protocol);
        if (fd != -1 && ( connect(fd, aip->ai_addr, aip->ai_addrlen) == 0))
@@ -282,7 +282,7 @@ InetTransport::initDataConnV6(fxStr& emsg)
                client.printWarning(NLS::TEXT("Couldn't parse last response \"%s\""), (const char*)client.getLastResponse());
                return(false);
            }
-       } else if (err == FaxClient::ERROR && data_addr.family == AF_INET) {
+       } else if (err == FaxClient::ERROR && Socket::family(data_addr) == AF_INET) {
 
            client.printWarning(NLS::TEXT("EPSV not supported, trying PASV since we're AF_INET\n"));
            if (client.command("PASV") != FaxClient::COMPLETE)
@@ -311,7 +311,7 @@ InetTransport::initDataConnV6(fxStr& emsg)
        Socket::port(data_addr) = 0;            // let system allocate port
     }
 
-    int fd = socket(data_addr.family, SOCK_STREAM, IPPROTO_TCP);
+    int fd = socket(Socket::family(data_addr), SOCK_STREAM, IPPROTO_TCP);
     if (fd < 0) {
        emsg = fxStr::format("socket: %s", strerror(errno));
        return (false);
@@ -320,10 +320,10 @@ InetTransport::initDataConnV6(fxStr& emsg)
        if (Socket::connect(fd, &data_addr.in, Socket::socklen(data_addr)) >= 0) {
            if (client.getVerbose())
                client.traceServer("Connected to %s at port %u.",
-               inet_ntop(data_addr.family, Socket::addr(data_addr), buf, sizeof(buf)), ntohs(Socket::port(data_addr)));
+               inet_ntop(Socket::family(data_addr), Socket::addr(data_addr), buf, sizeof(buf)), ntohs(Socket::port(data_addr)));
        } else {
            emsg = fxStr::format("Can not reach server at %s at port %u (%s).",
-               inet_ntop(data_addr.family, Socket::addr(data_addr), buf, sizeof(buf)), ntohs(Socket::port(data_addr)), strerror(errno));
+               inet_ntop(Socket::family(data_addr), Socket::addr(data_addr), buf, sizeof(buf)), ntohs(Socket::port(data_addr)), strerror(errno));
            goto bad;
        }
     } else {
@@ -348,9 +348,9 @@ InetTransport::initDataConnV6(fxStr& emsg)
                        hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
                        NI_NUMERICHOST | NI_NUMERICSERV);
        int err = client.command("EPRT |%d|%s|%s|",
-                       (data_addr.family == AF_INET6 ? 2 : 1),
+                       (Socket::family(data_addr) == AF_INET6 ? 2 : 1),
                        hostbuf, portbuf);
-       if (err == FaxClient::ERROR && data_addr.family == AF_INET)
+       if (err == FaxClient::ERROR && Socket::family(data_addr) == AF_INET)
        {
            if (client.getVerbose())
                    client.printWarning(NLS::TEXT("EPRT not supported, trying PORT"));
index 3d6b8bea148d21f5319268c3d12e816c6710d0d0..f3baf72ff2b9962cec3a1c57c2793a51df5ba3c3 100644 (file)
@@ -68,7 +68,7 @@ public:
 
     union Address
     {
-           sa_family_t family;
+           struct sockaddr s;
            struct sockaddr_in in;
            struct sockaddr_in6 in6;
            struct sockaddr_un un;
@@ -79,6 +79,8 @@ public:
 
     static socklen_t socklen(const Address& a);
     static size_t addrlen(const Address& a);
+
+    static sa_family_t& family(Address& a);
     static in_port_t& port(Address& a);
     static void* addr (Address& a);
 };
@@ -132,7 +134,7 @@ inline struct hostent* Socket::gethostbyname(const char* name)
 
 inline socklen_t Socket::socklen (const Address& a)
 {
-    switch (a.family)
+    switch (a.s.sa_family)
     {
        case AF_INET:
                return sizeof(a.in);
@@ -146,7 +148,7 @@ inline socklen_t Socket::socklen (const Address& a)
 
 inline size_t Socket::addrlen (const Address& a)
 {
-    switch (a.family)
+    switch (a.s.sa_family)
     {
        case AF_INET:
                return sizeof(a.in.sin_addr);
@@ -156,9 +158,14 @@ inline size_t Socket::addrlen (const Address& a)
     fxAssert(true, "Socket::addrlen on invalid Address");
     return 0;          // DEAD CODE
 }
+inline sa_family_t& Socket::family (Address& a)
+{
+    return a.s.sa_family;
+}
+
 inline in_port_t& Socket::port (Address& a)
 {
-    switch (a.family)
+    switch (a.s.sa_family)
     {
        case AF_INET:
                return a.in.sin_port;
@@ -171,7 +178,7 @@ inline in_port_t& Socket::port (Address& a)
 
 inline void* Socket::addr (Address& a)
 {
-    switch (a.family)
+    switch (a.s.sa_family)
     {
        case AF_INET:
            return (void*) &a.in.sin_addr;