X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/tripe/blobdiff_plain/de014da64011b21929158b746803d69cbfb05ee6..13a55605839046f6f42910de713f4a9b6c44dfd4:/peer.c diff --git a/peer.c b/peer.c index 0e2664bf..50dec936 100644 --- a/peer.c +++ b/peer.c @@ -100,7 +100,7 @@ static void p_ponged(peer *p, unsigned msg, buf *b) if (buf_getu32(b, &id) || (magic = buf_get(b, sizeof(pg->magic))) == 0 || BLEFT(b)) { - a_warn("PEER %s malformed-%s", p->spec.name, p_pingtype(msg)); + a_warn("PEER", "?PEER", p, "malformed-%s", p_pingtype(msg), A_END); return; } @@ -108,13 +108,16 @@ static void p_ponged(peer *p, unsigned msg, buf *b) if (pg->id == id) goto found; } - a_warn("PEER %s unexpected-%s 0x%08lx", - p->spec.name, p_pingtype(msg), (unsigned long)id); + a_warn("PEER", + "?PEER", p, + "unexpected-%s", p_pingtype(msg), + "0x%08lx", (unsigned long)id, + A_END); return; found: if (memcmp(magic, pg->magic, sizeof(pg->magic)) != 0) { - a_warn("PEER %s corrupt-%s", p->spec.name, p_pingtype(msg)); + a_warn("PEER", "?PEER", p, "corrupt-%s", p_pingtype(msg), A_END); return; } p_pingdone(pg, PING_OK); @@ -133,7 +136,7 @@ found: static void p_read(int fd, unsigned mode, void *v) { - peer *p; + peer *p = 0; addr a; size_t sz; ssize_t n; @@ -146,7 +149,29 @@ static void p_read(int fd, unsigned mode, void *v) sz = sizeof(addr); n = recvfrom(fd, buf_i, sizeof(buf_i), 0, &a.sa, &sz); if (n < 0) { - a_warn("PEER - socket-read-error -- %s", strerror(errno)); + a_warn("PEER", "-", "socket-read-error", "?ERRNO", A_END); + return; + } + + /* --- If the packet is a greeting, don't check peers --- */ + + if (n && buf_i[0] == (MSG_MISC | MISC_GREET)) { + IF_TRACING(T_PEER, { + trace(T_PEER, "peer: greeting received from INET %s %u", + inet_ntoa(a.sin.sin_addr), + (unsigned)ntohs(a.sin.sin_port)); + trace_block(T_PACKET, "peer: greeting contents", buf_i, n); + }) + buf_init(&b, buf_i, n); + buf_getbyte(&b); + if (c_check(&b) || BLEFT(&b)) { + a_warn("PEER", "-", "invalid-greeting", A_END); + return; + } + a_notify("GREET", + "?B64", buf_i + 1, (size_t)(n - 1), + "?ADDR", &a, + A_END); return; } @@ -158,8 +183,7 @@ static void p_read(int fd, unsigned mode, void *v) p->spec.sa.sin.sin_port == a.sin.sin_port) goto found; } - a_warn("PEER - unexpected-source INET %s %u", - inet_ntoa(a.sin.sin_addr), (unsigned)ntohs(a.sin.sin_port)); + a_warn("PEER", "-", "unexpected-source", "?ADDR", &a, A_END); return; found: @@ -175,20 +199,24 @@ found: p->st.sz_in += n; buf_init(&b, buf_i, n); if ((ch = buf_getbyte(&b)) < 0) { - a_warn("PEER %s bad-packet no-type", p->spec.name); + a_warn("PEER", "?PEER", p, "bad-packet", "no-type", A_END); return; } switch (ch & MSG_CATMASK) { case MSG_PACKET: if (ch & MSG_TYPEMASK) { - a_warn("PEER %s bad-packet unknown-type 0x%02x", p->spec.name, ch); + a_warn("PEER", + "?PEER", p, + "bad-packet", + "unknown-type", "0x%02x", ch, + A_END); p->st.n_reject++; return; } buf_init(&bb, buf_o, sizeof(buf_o)); if (ksl_decrypt(&p->ks, MSG_PACKET, &b, &bb)) { p->st.n_reject++; - a_warn("PEER %s decrypt-failed", p->spec.name); + a_warn("PEER", "?PEER", p, "decrypt-failed", A_END); return; } if (BOK(&bb)) { @@ -197,7 +225,7 @@ found: p->t->ops->inject(p->t, &bb); } else { p->st.n_reject++; - a_warn("PEER %s packet-build-failed", p->spec.name); + a_warn("PEER", "?PEER", p, "packet-build-failed", A_END); } break; case MSG_KEYEXCH: @@ -219,7 +247,7 @@ found: buf_init(&bb, buf_t, sizeof(buf_t)); if (ksl_decrypt(&p->ks, ch, &b, &bb)) { p->st.n_reject++; - a_warn("PEER %s decrypt-failed", p->spec.name); + a_warn("PEER", "?PEER", "decrypt-failed", A_END); return; } if (BOK(&bb)) { @@ -234,7 +262,7 @@ found: buf_init(&bb, buf_t, sizeof(buf_t)); if (ksl_decrypt(&p->ks, ch, &b, &bb)) { p->st.n_reject++; - a_warn("PEER %s decrypt-failed", p->spec.name); + a_warn("PEER", "?PEER", p, "decrypt-failed", A_END); return; } if (BOK(&bb)) { @@ -246,7 +274,11 @@ found: break; default: p->st.n_reject++; - a_warn("PEER %s bad-packet unknown-category 0x%02x", p->spec.name, ch); + a_warn("PEER", + "?PEER", p, + "bad-packet", + "unknown-category" "0x%02x", ch, + A_END); break; } } @@ -283,15 +315,14 @@ static void p_setkatimer(peer *); static int p_dotxend(peer *p) { if (!BOK(&p->b)) { - a_warn("PEER %s packet-build-failed", p->spec.name); + a_warn("PEER", "?PEER", p, "packet-build-failed", A_END); return (0); } 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) { - a_warn("PEER %s socket-write-error -- %s", - p->spec.name, strerror(errno)); + a_warn("PEER", "?PEER", p, "socket-write-error", "?ERRNO", A_END); return (0); } else { p->st.n_out++; @@ -340,12 +371,12 @@ static void p_pingwrite(ping *p, buf *b) void p_pingdone(ping *p, int rc) { - if (!p->p) return; if (p->prev) p->prev->next = p->next; else p->p->pings = p->next; if (p->next) p->next->prev = p->prev; if (rc != PING_TIMEOUT) sel_rmtimer(&p->t); - p->p = 0; + T( trace(T_PEER, "peer: ping 0x%08lx done (rc = %d)", + (unsigned long)p->id, rc); ) if (rc >= 0) p->func(rc, p->arg); } @@ -418,6 +449,7 @@ int p_pingsend(peer *p, ping *pg, unsigned type, pg->p = p; pg->func = func; pg->arg = arg; + if (p->pings) p->pings->prev = pg; p->pings = pg; gettimeofday(&tv, 0); tv.tv_sec += timeout; @@ -427,6 +459,24 @@ int p_pingsend(peer *p, ping *pg, unsigned type, return (0); } +/* --- @p_greet@ --- * + * + * Arguments: @peer *p@ = peer to send to + * @const void *c@ = pointer to challenge + * @size_t sz@ = size of challenge + * + * Returns: --- + * + * Use: Sends a greeting packet. + */ + +void p_greet(peer *p, const void *c, size_t sz) +{ + buf *b = p_txstart(p, MSG_MISC | MISC_GREET); + buf_put(b, c, sz); + p_txend(p); +} + /* --- @p_tun@ --- * * * Arguments: @peer *p@ = pointer to peer block @@ -645,19 +695,13 @@ peer *p_create(peerspec *spec) if (peers) peers->prev = p; peers = p; - switch (p->spec.sa.sa.sa_family) { - case AF_INET: - a_notify("ADD %s %s INET %s %u", - spec->name, - p->t->ops->ifname(p->t), - inet_ntoa(p->spec.sa.sin.sin_addr), - (unsigned)ntohs(p->spec.sa.sin.sin_port)); - break; - default: - a_notify("ADD %s %s UNKNOWN", spec->name, p->t->ops->ifname(p->t)); - break; - } - a_notify("KXSTART %s", spec->name); /* Couldn't tell anyone before */ + a_notify("ADD", + "?PEER", p, + "%s", p->t->ops->ifname(p->t), + "?ADDR", &p->spec.sa, + A_END); + a_notify("KXSTART", "?PEER", p, A_END); + /* Couldn't tell anyone before */ return (p); tidy_1: @@ -679,6 +723,15 @@ tidy_0: const char *p_name(peer *p) { return (p->spec.name); } +/* --- @p_spec@ --- * + * + * Arguments: @peer *p@ = pointer to a peer block + * + * Returns: Pointer to the peer's specification + */ + +const peerspec *p_spec(peer *p) { return (&p->spec); } + /* --- @p_find@ --- * * * Arguments: @const char *name@ = name to look up @@ -712,7 +765,7 @@ void p_destroy(peer *p) ping *pg, *ppg; T( trace(T_PEER, "peer: destroying peer `%s'", p->spec.name); ) - a_notify("KILL %s", p->spec.name); + a_notify("KILL", "%s", p->spec.name, A_END); ksl_free(&p->ks); kx_free(&p->kx); p->t->ops->destroy(p->t);