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;
}
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);
static void p_read(int fd, unsigned mode, void *v)
{
- peer *p;
+ peer *p = 0;
addr a;
size_t sz;
ssize_t n;
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;
}
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:
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)) {
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:
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)) {
buf_flip(&bb);
if (ksl_encrypt(&p->ks, MSG_MISC | MISC_EPONG, &bb,
p_txstart(p, MSG_MISC | MISC_EPONG)))
- kx_start(&p->kx);
+ kx_start(&p->kx, 0);
p_txend(p);
}
break;
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)) {
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;
}
}
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++;
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);
}
buf *b, bb;
struct timeval tv;
- assert(!pg->p);
-
switch (type) {
case MISC_PING:
pg->msg = MISC_PONG;
p_pingwrite(pg, &bb);
buf_flip(&bb);
if (ksl_encrypt(&p->ks, MSG_MISC | MISC_EPING, &bb, b))
- kx_start(&p->kx);
+ kx_start(&p->kx, 0);
if (!BOK(b))
return (-1);
p_txend(p);
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;
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
TIMER;
if (ksl_encrypt(&p->ks, MSG_PACKET, b, bb))
- kx_start(&p->kx);
+ kx_start(&p->kx, 0);
if (BOK(bb) && BLEN(bb)) {
p->st.n_ipout++;
p->st.sz_ipout += BLEN(bb);
}
}
+/* --- @p_keyreload@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Forces a check of the daemon's keyring files.
+ */
+
+void p_keyreload(void)
+{
+ peer *p;
+
+ if (km_reload()) {
+ for (p = peers; p; p = p->next)
+ kx_newkeys(&p->kx);
+ }
+}
+
/* --- @p_interval@ --- *
*
* Arguments: ---
void p_interval(void)
{
- peer *p, *pp;
- int reload;
+ peer *p;
- reload = km_interval();
- for (p = peers; p; p = pp) {
- pp = p->next;
- if (reload)
- kx_newkeys(&p->kx);
+ p_keyreload();
+ for (p = peers; p; p = p->next)
ksl_prune(&p->ks);
- }
}
/* --- @p_stats@ --- *
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:
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
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);