X-Git-Url: https://git.distorted.org.uk/~mdw/tripe/blobdiff_plain/98b9b13628a7613868e0fda618e6303961932550..9d966eb7af70d029a9b4862efb67b0c90d32688e:/server/peer.c diff --git a/server/peer.c b/server/peer.c index 278a6b2a..95306836 100644 --- a/server/peer.c +++ b/server/peer.c @@ -809,14 +809,14 @@ const addr *p_addr(peer *p) { return (&p->spec.sa); } * * Arguments: @struct addrinfo *ailist@ = addresses to bind to * - * Returns: --- + * Returns: Zero on success, @-1@ on failure. * - * Use: Initializes the peer system; creates the socket. + * Use: Binds to the main UDP sockets. */ -void p_bind(struct addrinfo *ailist) +int p_bind(struct addrinfo *ailist) { - int fd; + int fd = -1; int len = PKBUFSZ; int yes = 1; int i; @@ -842,13 +842,13 @@ void p_bind(struct addrinfo *ailist) if ((fd = socket(ai->ai_family, SOCK_DGRAM, 0)) < 0) { a_warn("PEER", "-", "udp-socket", "%s", aftab[i].name, "create-failed", "?ERRNO", A_END); - exit(EXIT_FAILURE); + goto fail; } if (i == AFIX_INET6 && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes))) { a_warn("PEER", "-", "udp-socket", "%s", aftab[i].name, "set-v6only-failed", "?ERRNO", A_END); - exit(EXIT_FAILURE); + goto fail; } assert(ai->ai_addrlen <= sizeof(a)); memcpy(&a, ai->ai_addr, ai->ai_addrlen); @@ -856,13 +856,13 @@ void p_bind(struct addrinfo *ailist) if (bind(fd, &a.sa, addrsz(&a))) { a_warn("PEER", "-", "udp-socket", "%s", aftab[i].name, "bind-failed", "?ERRNO", A_END); - exit(EXIT_FAILURE); + goto fail; } if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len)) || setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &len, sizeof(len))) { a_warn("PEER", "-", "udp-socket", "%s", aftab[i].name, "set-buffers-failed", "?ERRNO", A_END); - exit(EXIT_FAILURE); + goto fail; } fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC); if (port) @@ -872,15 +872,22 @@ void p_bind(struct addrinfo *ailist) if (getsockname(fd, &a.sa, &sz)) { a_warn("PEER", "-", "udp-socket", "%s", aftab[i].name, "read-local-address-failed", "?ERRNO", A_END); - exit(EXIT_FAILURE); + goto fail; } udpsock[i].port = lastport = getport(&a); } T( trace(T_PEER, "peer: created %s socket", aftab[i].name); ) sel_initfile(&sel, &udpsock[i].sf, fd, SEL_READ, p_read, 0); sel_addfile(&udpsock[i].sf); + fd = -1; } + return (0); + +fail: + if (fd != -1) close(fd); + p_unbind(); + return (-1); } /* --- @p_unbind@ --- * @@ -928,28 +935,29 @@ void p_init(void) * * Arguments: @const tunnel_ops *tops@ = tunnel ops to add * - * Returns: --- + * Returns: Zero on success, @-1@ on failure. * - * Use: Adds a tunnel class to the list of known classes. If there - * is no current default tunnel, then this one is made the - * default. + * Use: Adds a tunnel class to the list of known classes, if it + * initializes properly. If there is no current default tunnel, + * then this one is made the default. * * Does nothing if the tunnel class is already known. So adding * a bunch of tunnels takes quadratic time, but there will be * too few to care about. */ -void p_addtun(const tunnel_ops *tops) +int p_addtun(const tunnel_ops *tops) { struct tunnel_node *tn; for (tn = tunnels; tn; tn = tn->next) - if (tn->tops == tops) return; - tops->init(); + if (tn->tops == tops) return (0); + if (tops->init()) return (-1); tn = CREATE(struct tunnel_node); tn->next = 0; tn->tops = tops; *tunnels_tail = tn; tunnels_tail = &tn->next; if (!dflttun) dflttun = tops; + return (0); } /* --- @p_setdflttun@ --- *