X-Git-Url: https://git.distorted.org.uk/~mdw/secnet/blobdiff_plain/08b62a6c691fe0e772c74de9d60803afcb7d2aa9..32fc582f43a9a3841d2782674e055113729c2814:/udp.c diff --git a/udp.c b/udp.c index fe60368..bb8d9ef 100644 --- a/udp.c +++ b/udp.c @@ -30,11 +30,12 @@ static comm_request_notify_fn request_notify; static comm_release_notify_fn release_notify; static comm_sendmsg_fn udp_sendmsg; -struct notify_list { +struct comm_notify_entry { comm_notify_fn *fn; void *state; - struct notify_list *next; + LIST_ENTRY(comm_notify_entry) entry; }; +LIST_HEAD(comm_notify_list, comm_notify_entry) notify; #define MAX_SOCKETS 3 /* 2 ought to do really */ @@ -51,7 +52,7 @@ struct udp { struct udpsock socks[MAX_SOCKETS]; string_t authbind; struct buffer_if *rbuf; - struct notify_list *notify; + struct comm_notify_list notify; bool_t use_proxy; union iaddr proxy; }; @@ -86,11 +87,7 @@ static int udp_beforepoll(void *state, struct pollfd *fds, int *nfds_io, { int i; struct udp *st=state; - if (*nfds_ion_socks) { - *nfds_io=st->n_socks; - return ERANGE; - } - *nfds_io=st->n_socks; + BEFOREPOLL_WANT_FDS(st->n_socks); for (i=0; in_socks; i++) { fds[i].fd=st->socks[i].fd; fds[i].events=POLLIN; @@ -103,7 +100,7 @@ static void udp_afterpoll(void *state, struct pollfd *fds, int nfds) struct udp *st=state; union iaddr from; socklen_t fromlen; - struct notify_list *n; + struct comm_notify_entry *n; bool_t done; int rv; int i; @@ -144,7 +141,7 @@ static void udp_afterpoll(void *state, struct pollfd *fds, int nfds) ca.ia=from; ca.ix=i; done=False; - for (n=st->notify; n; n=n->next) { + LIST_FOREACH(n, &st->notify, entry) { if (n->fn(n->state, st->rbuf, &ca)) { done=True; break; @@ -174,32 +171,24 @@ static void udp_afterpoll(void *state, struct pollfd *fds, int nfds) static void request_notify(void *commst, void *nst, comm_notify_fn *fn) { struct udp *st=commst; - struct notify_list *n; + struct comm_notify_entry *n; n=safe_malloc(sizeof(*n),"request_notify"); n->fn=fn; n->state=nst; - n->next=st->notify; - st->notify=n; + LIST_INSERT_HEAD(&st->notify, n, entry); } static void release_notify(void *commst, void *nst, comm_notify_fn *fn) { struct udp *st=commst; - struct notify_list *n, **p, *t; + struct comm_notify_entry *n, *t; /* XXX untested */ - p=&st->notify; - for (n=st->notify; n; ) - { + LIST_FOREACH_SAFE(n, &st->notify, entry, t) { if (n->state==nst && n->fn==fn) { - t=n; - *p=n->next; - n=n->next; - free(t); - } else { - p=&n->next; - n=n->next; + LIST_REMOVE(n, entry); + free(n); } } } @@ -278,20 +267,35 @@ static void udp_make_socket(struct udp *st, struct udpsock *us) fatal_perror("udp_phase_hook: fork() for authbind"); } if (c==0) { - char *argv[4], addrstr[9], portstr[5]; + char *argv[5], addrstr[33], portstr[5]; + const char *addrfam; + int port; switch (addr->sa.sa_family) { case AF_INET: sprintf(addrstr,"%08lX",(long)addr->sin.sin_addr.s_addr); - sprintf(portstr,"%04X",addr->sin.sin_port); + port=addr->sin.sin_port; + addrfam=NULL; break; +#ifdef CONFIG_IPV6 + case AF_INET6: { + int i; + for (i=0; i<16; i++) + sprintf(addrstr+i*2,"%02X",addr->sin6.sin6_addr.s6_addr[i]); + port=addr->sin6.sin6_port; + addrfam="6"; + break; + } +#endif /*CONFIG_IPV6*/ default: fatal("udp (%s:%d): unsupported address family for authbind", st->loc.file,st->loc.line); } + sprintf(portstr,"%04X",port); argv[0]=st->authbind; argv[1]=addrstr; argv[2]=portstr; - argv[3]=NULL; + argv[3]=(char*)addrfam; + argv[4]=NULL; dup2(us->fd,0); execvp(st->authbind,argv); _exit(255); @@ -322,7 +326,7 @@ static void udp_phase_hook(void *sst, uint32_t new_phase) for (i=0; in_socks; i++) udp_make_socket(st,&st->socks[i]); - register_for_poll(st,udp_beforepoll,udp_afterpoll,MAX_SOCKETS,"udp"); + register_for_poll(st,udp_beforepoll,udp_afterpoll,"udp"); } static list_t *udp_apply(closure_t *self, struct cloc loc, dict_t *context, @@ -348,6 +352,7 @@ static list_t *udp_apply(closure_t *self, struct cloc loc, dict_t *context, st->ops.sendmsg=udp_sendmsg; st->ops.addr_to_string=addr_to_string; st->use_proxy=False; + LIST_INIT(&st->notify); item=list_elem(args,0); if (!item || item->type!=t_dict) {