On Wed, Sep 17, 2014 at 06:48:28PM +0200, Mark Martinec wrote:

> Was investigating why I can't connect to my smtp-sink:
> 
> $ smtp-sink -v [::1]:10055 10
> smtp-sink: name_mask: all
> smtp-sink: trying... [::1]:10055
> 
>   then in another window: $ smtp-source [::1]:10055
> 
>   and the smtp-sink aborts with:
> 
> smtp-sink: fatal: sockaddr_to_hostaddr: Non-recoverable failure in name
> resolution
> 
> 
> Turns out that the problem is a structure declared too short
> by two bytes to receive a sockaddr_in6 from accept(),
> and the two bytes of a received IP address are then clobbered.
> 
> In smtp-sink.c/connect_event() the sa is declared
> as struct sockaddr instead of struct sockaddr_storage
> (RFC 3493).
> 
> Seems like elsewhere this is handled correctly
> ( like in inet_listen.c/inet_accept() ).

I gather you're suggesting a chang along the lines of:

diff --git a/src/smtpstone/smtp-sink.c b/src/smtpstone/smtp-sink.c
index 617fbf9..33872b0 100644
--- a/src/smtpstone/smtp-sink.c
+++ b/src/smtpstone/smtp-sink.c
@@ -1298,31 +1298,32 @@ static void disconnect(SINK_STATE *state)
 
 static void connect_event(int unused_event, char *unused_context)
 {
-    struct sockaddr sa;
-    SOCKADDR_SIZE len = sizeof(sa);
+    struct sockaddr_storage ss;
+    struct sockaddr *sa = (struct sockaddr *)&ss;
+    SOCKADDR_SIZE salen = sizeof(ss);
     SINK_STATE *state;
     int     fd;
 
-    if ((fd = sane_accept(sock, &sa, &len)) >= 0) {
+    if ((fd = sane_accept(sock, sa, &salen)) >= 0) {
        /* Safety: limit the number of open sockets and capture files. */
        if (++client_count == max_client_count)
            event_disable_readwrite(sock);
        state = (SINK_STATE *) mymalloc(sizeof(*state));
-       if (strchr((char *) proto_info->sa_family_list, sa.sa_family))
-           SOCKADDR_TO_HOSTADDR(&sa, len, &state->client_addr,
-                                (MAI_SERVPORT_STR *) 0, sa.sa_family);
+       if (strchr((char *) proto_info->sa_family_list, sa->sa_family))
+           SOCKADDR_TO_HOSTADDR(sa, salen, &state->client_addr,
+                                (MAI_SERVPORT_STR *) 0, sa->sa_family);
        else
            strncpy(state->client_addr.buf, "local", sizeof("local"));
        if (msg_verbose)
            msg_info("connect (%s %s)",
 #ifdef AF_LOCAL
-                    sa.sa_family == AF_LOCAL ? "AF_LOCAL" :
+                    sa->sa_family == AF_LOCAL ? "AF_LOCAL" :
 #else
-                    sa.sa_family == AF_UNIX ? "AF_UNIX" :
+                    sa->sa_family == AF_UNIX ? "AF_UNIX" :
 #endif
-                    sa.sa_family == AF_INET ? "AF_INET" :
+                    sa->sa_family == AF_INET ? "AF_INET" :
 #ifdef AF_INET6
-                    sa.sa_family == AF_INET6 ? "AF_INET6" :
+                    sa->sa_family == AF_INET6 ? "AF_INET6" :
 #endif
                     "unknown protocol family",
                     state->client_addr.buf);
@@ -1340,7 +1341,7 @@ static void connect_event(int unused_event, char 
*unused_context)
        state->delayed_args = 0;
        /* Initialize file capture attributes. */
 #ifdef AF_INET6
-       if (sa.sa_family == AF_INET6)
+       if (sa->sa_family == AF_INET6)
            state->addr_prefix = "ipv6:";
        else
 #endif

-- 
        Viktor.

Reply via email to