chiark / gitweb /
comm: Move construction of comm_addr behind comm interface.
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 21 Jul 2011 13:24:11 +0000 (14:24 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 27 Aug 2011 15:43:22 +0000 (16:43 +0100)
Now only the specific comm is allowed to construct a comm_addr; site
no longer does so.  It passes the sockaddr_in containing the address
and port number from the configuration.  This paves the way for more
exciting kinds of comm.

No international functional change.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
secnet.h
site.c
udp.c

index fbb7660da685e8721aac0a56a4e017845ffd69f5..d330f64c5323bc720b1379fd6333455b33ea4691 100644 (file)
--- a/secnet.h
+++ b/secnet.h
@@ -308,11 +308,11 @@ struct comm_addr {
        freely copy it. */
     /* Everyone is also guaranteed that all padding is set to zero, ie
        that comm_addrs referring to semantically identical peers will
-       compare equal with memcmp.  Anyone who constructs a comm_addr
-       must start by memsetting it with FILLZERO, or some
-       equivalent. */
+       compare equal with memcmp. */
     struct comm_if *comm;
-    struct sockaddr_in sin;
+    union {
+       struct sockaddr_in sin;
+    } priv;
 };
 
 /* Return True if the packet was processed, and shouldn't be passed to
@@ -325,6 +325,12 @@ typedef void comm_release_notify_fn(void *commst, void *nst,
                                    comm_notify_fn *fn);
 typedef bool_t comm_sendmsg_fn(void *commst, struct buffer_if *buf,
                               const struct comm_addr *dest);
+typedef bool_t comm_addr_construct_fn(void *commst, struct comm_addr *ca,
+                                     const struct sockaddr_in *sin);
+       /* Fills in ca->comm an ca->priv.  *sin must have no nonzero padding,
+          so must have been FILLZERO'd before its useful fields were filled in.
+          The resulting ca->comm has been constructed likewise, as required
+          above.  On failure, logs error, returns false on failure.*/
 typedef const char *comm_addr_to_string_fn(void *commst,
                                           const struct comm_addr *ca);
         /* Returned string is in a static buffer. */
@@ -335,6 +341,7 @@ struct comm_if {
     comm_request_notify_fn *request_notify;
     comm_release_notify_fn *release_notify;
     comm_sendmsg_fn *sendmsg;
+    comm_addr_construct_fn *addr_construct;
     comm_addr_to_string_fn *addr_to_string;
 };
 
diff --git a/site.c b/site.c
index 624752cec98bcd46f8dbc1ed1c01d313091f59b6..40819a4ab43a653d99a0df216e8d2f8faae5106a 100644 (file)
--- a/site.c
+++ b/site.c
@@ -796,22 +796,23 @@ static bool_t send_msg(struct site *st)
 static void site_resolve_callback(void *sst, struct in_addr *address)
 {
     struct site *st=sst;
-    struct comm_addr ca_buf, *ca_use;
+    struct comm_addr ca_buf, *ca_use=0;
 
     if (st->state!=SITE_RESOLVE) {
        slog(st,LOG_UNEXPECTED,"site_resolve_callback called unexpectedly");
        return;
     }
     if (address) {
-       FILLZERO(ca_buf);
-       ca_buf.comm=st->comms[0];
-       ca_buf.sin.sin_family=AF_INET;
-       ca_buf.sin.sin_port=htons(st->remoteport);
-       ca_buf.sin.sin_addr=*address;
-       ca_use=&ca_buf;
+       struct sockaddr_in sin;
+       FILLZERO(sin);
+       sin.sin_family=AF_INET;
+       sin.sin_port=htons(st->remoteport);
+       sin.sin_addr=*address;
+       if (st->comms[0]->addr_construct(st->comms[0]->st, &ca_buf, &sin)) {
+           ca_use=&ca_buf;
+       }
     } else {
        slog(st,LOG_ERROR,"resolution of %s failed",st->address);
-       ca_use=0;
     }
     if (transport_compute_setupinit_peers(st,ca_use)) {
        enter_new_state(st,SITE_SENTMSG1);
diff --git a/udp.c b/udp.c
index f4206642fc15f44f1de6606bd970c6e2449797f4..a1d3b74f5b1b6d7d1963f9e38c8048622be7f844 100644 (file)
--- a/udp.c
+++ b/udp.c
@@ -68,10 +68,19 @@ static const char *addr_to_string(void *commst, const struct comm_addr *ca) {
     la.sin_port=htons(st->port);
 
     snprintf(sbuf, sizeof(sbuf), "udp:%s-%s",
-            saddr_to_string(&la), saddr_to_string(&ca->sin));
+            saddr_to_string(&la), saddr_to_string(&ca->priv.sin));
     return sbuf;
 }
 
+static bool_t addr_construct(void *commst, struct comm_addr *ca,
+                            const struct sockaddr_in *sin) {
+    struct udp *st=commst;
+    FILLZERO(*ca);
+    ca->comm=&st->ops;
+    ca->priv.sin=*sin;
+    return True;
+}
+
 static int udp_beforepoll(void *state, struct pollfd *fds, int *nfds_io,
                          int *timeout_io)
 {
@@ -125,7 +134,7 @@ static void udp_afterpoll(void *state, struct pollfd *fds, int nfds)
                    struct comm_addr ca;
                    FILLZERO(ca);
                    ca.comm=&st->ops;
-                   ca.sin=from;
+                   ca.priv.sin=from;
                    if (n->fn(n->state, st->rbuf, &ca)) {
                        done=True;
                        break;
@@ -194,14 +203,14 @@ static bool_t udp_sendmsg(void *commst, struct buffer_if *buf,
 
     if (st->use_proxy) {
        sa=buf->start-8;
-       memcpy(sa,&dest->sin.sin_addr,4);
+       memcpy(sa,&dest->priv.sin.sin_addr,4);
        memset(sa+4,0,4);
-       memcpy(sa+6,&dest->sin.sin_port,2);
+       memcpy(sa+6,&dest->priv.sin.sin_port,2);
        sendto(st->fd,sa,buf->size+8,0,(struct sockaddr *)&st->proxy,
               sizeof(st->proxy));
     } else {
        sendto(st->fd, buf->start, buf->size, 0,
-              (struct sockaddr *)&dest->sin, sizeof(dest->sin));
+              (struct sockaddr *)&dest->priv.sin, sizeof(dest->priv.sin));
     }
 
     return True;
@@ -293,6 +302,7 @@ static list_t *udp_apply(closure_t *self, struct cloc loc, dict_t *context,
     st->ops.request_notify=request_notify;
     st->ops.release_notify=release_notify;
     st->ops.sendmsg=udp_sendmsg;
+    st->ops.addr_construct=addr_construct;
     st->ops.addr_to_string=addr_to_string;
     st->port=0;
     st->use_proxy=False;