X-Git-Url: https://git.distorted.org.uk/~mdw/tripe/blobdiff_plain/fe2a5dcf9de1f124ed3cfa2c6327860bd5aca820..0510f26241da5ac18afecf97fa46e0448ae705a4:/server/peer.c diff --git a/server/peer.c b/server/peer.c index 75f7acba..e9b8f668 100644 --- a/server/peer.c +++ b/server/peer.c @@ -9,19 +9,18 @@ * * This file is part of Trivial IP Encryption (TrIPE). * - * TrIPE is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * TrIPE is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your + * option) any later version. * - * TrIPE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * TrIPE is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. * * You should have received a copy of the GNU General Public License - * along with TrIPE; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * along with TrIPE. If not, see . */ /*----- Header files ------------------------------------------------------*/ @@ -167,6 +166,51 @@ static int p_encrypt(peer *p, int ty, buf *bin, buf *bout) return (err); } +/* --- @p_updateaddr@ --- * + * + * Arguments: @peer *p@ = pointer to peer block + * @const addr *a@ = address to associate with this peer + * + * Returns: Zero if the address was changed; @+1@ if it was already + * right. + * + * Use: Updates our idea of @p@'s address. + */ + +int p_updateaddr(peer *p, const addr *a) +{ + peer *q; + peer_byaddr *pa, *qa; + unsigned f; + + /* --- Figure out how to proceed --- * + * + * If this address already belongs to a different peer, then swap the + * addresses over. This doesn't leave the displaced peer in an especially + * good state, but it ought to get sorted out soon enough. + */ + + pa = am_find(&byaddr, a, sizeof(peer_byaddr), &f); + if (f && pa->p == p) + return (+1); + else if (!f) { + T( trace(T_PEER, "peer: updating address for `%s'", p_name(p)); ) + am_remove(&byaddr, p->byaddr); + p->byaddr = pa; p->spec.sa = *a; pa->p = p; + a_notify("NEWADDR", "?PEER", p, "?ADDR", a, A_END); + return (0); + } else { + q = pa->p; qa = p->byaddr; + T( trace(T_PEER, "peer: swapping addresses for `%s' and `%s'", + p_name(p), p_name(q)); ) + q->byaddr = qa; qa->p = q; q->spec.sa = p->spec.sa; + p->byaddr = pa; pa->p = p; p->spec.sa = *a; + a_notify("NEWADDR", "?PEER", p, "?ADDR", a, A_END); + a_notify("NEWADDR", "?PEER", q, "?ADDR", &q->spec.sa, A_END); + return (0); + } +} + /* --- @p_decrypt@ --- * * * Arguments: @peer **pp@ = pointer to peer to decrypt message from @@ -189,9 +233,7 @@ static int p_decrypt(peer **pp, addr *a, size_t n, int ty, buf *bin, buf *bout) { peer *p, *q; - peer_byaddr *pa, *qa; int err = KSERR_DECRYPT; - unsigned f; /* --- If we have a match on the source address then try that first --- */ @@ -204,10 +246,9 @@ static int p_decrypt(peer **pp, addr *a, size_t n, p = q; goto match; } - T( trace(T_PEER, "peer: failed to decrypt: try other mobile peers...", - p_name(q)); ) + T( trace(T_PEER, "peer: failed to decrypt: try other mobile peers..."); ) } else if (nmobile) - T( trace(T_PEER, "peer: unknown source: trying mobile peers..."); ) + T( trace(T_PEER, "peer: unknown source: trying mobile peers...") ); else { p = 0; goto searched; @@ -250,33 +291,11 @@ searched: return (-1); } - /* --- We found one that accepted, so update the peer's address --- * - * - * If we had an initial guess of which peer this packet came from -- i.e., - * @q@ is not null -- then swap the addresses over. This doesn't leave the - * evicted peer in an especially good state, but it ought to get sorted out - * soon enough. - */ + /* --- We found one that accepted, so update the peer's address --- */ if (!err) { *pp = p; - if (!q) { - T( trace(T_PEER, "peer: updating address for `%s'", p_name(p)); ) - pa = am_find(&byaddr, a, sizeof(peer_byaddr), &f); assert(!f); - am_remove(&byaddr, p->byaddr); - p->byaddr = pa; - pa->p = p; - p->spec.sa = *a; - a_notify("NEWADDR", "?PEER", p, "?ADDR", a, A_END); - } else { - T( trace(T_PEER, "peer: swapping addresses for `%s' and `%s'", - p_name(p), p_name(q)); ) - pa = p->byaddr; qa = q->byaddr; - pa->p = q; q->byaddr = pa; q->spec.sa = p->spec.sa; - qa->p = p; p->byaddr = qa; p->spec.sa = *a; - a_notify("NEWADDR", "?PEER", p, "?ADDR", a, A_END); - a_notify("NEWADDR", "?PEER", q, "?ADDR", &q->spec.sa, A_END); - } + p_updateaddr(p, a); } match: @@ -307,14 +326,14 @@ static void p_read(int fd, unsigned mode, void *v) { peer *p = 0; addr a; - size_t sz; + socklen_t sz; ssize_t n; int ch; buf b, bb; /* --- Read the data --- */ - TIMER; + QUICKRAND; sz = sizeof(addr); n = recvfrom(fd, buf_i, sizeof(buf_i), 0, &a.sa, &sz); if (n < 0) { @@ -333,7 +352,7 @@ static void p_read(int fd, unsigned mode, void *v) }) buf_init(&b, buf_i, n); buf_getbyte(&b); - if (c_check(&b) || BLEFT(&b)) { + if (c_check(0, 0, &b) || BLEFT(&b)) { a_warn("PEER", "-", "invalid-greeting", A_END); return; } @@ -483,6 +502,8 @@ static void p_setkatimer(peer *); static int p_dotxend(peer *p) { + socklen_t sasz = addrsz(&p->spec.sa); + if (!BOK(&p->b)) { a_warn("PEER", "?PEER", p, "packet-build-failed", A_END); return (0); @@ -490,7 +511,7 @@ static int p_dotxend(peer *p) IF_TRACING(T_PEER, trace_block(T_PACKET, "peer: sending packet", BBASE(&p->b), BLEN(&p->b)); ) if (sendto(sock.fd, BBASE(&p->b), BLEN(&p->b), - 0, &p->spec.sa.sa, p->spec.sasz) < 0) { + 0, &p->spec.sa.sa, sasz) < 0) { a_warn("PEER", "?PEER", p, "socket-write-error", "?ERRNO", A_END); return (0); } else { @@ -659,7 +680,7 @@ void p_tun(peer *p, buf *b) { buf *bb = p_txstart(p, MSG_PACKET); - TIMER; + QUICKRAND; p_encrypt(p, MSG_PACKET, b, bb); if (BOK(bb) && BLEN(bb)) { p->st.n_ipout++; @@ -799,7 +820,7 @@ void p_init(struct in_addr addr, unsigned port) unsigned p_port(void) { addr a; - size_t sz = sizeof(addr); + socklen_t sz = sizeof(addr); if (getsockname(sock.fd, &a.sa, &sz)) die(EXIT_FAILURE, "couldn't read port number: %s", strerror(errno)); @@ -888,7 +909,7 @@ peer *p_create(peerspec *spec) T( trace(T_TUNNEL, "peer: attached interface %s to peer `%s'", p->ifname, p_name(p)); ) p_setkatimer(p); - if (kx_init(&p->kx, p, &p->ks, p->spec.f & PSF_KXMASK)) + if (kx_setup(&p->kx, p, &p->ks, p->spec.f & PSF_KXMASK)) goto tidy_4; a_notify("ADD", "?PEER", p,