aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Dunwoodie <ncon@mail.noconroy.net>2019-09-22 21:16:18 +0200
committerMatt Dunwoodie <ncon@mail.noconroy.net>2019-09-22 21:16:18 +0200
commitb4e5605a406b41e5edc9256e4f0cca1170ebadec (patch)
tree4d332800b39814251d9a88c254c37a7218de26c6
parentAdd more documentation :) (diff)
downloadwireguard-openbsd-b4e5605a406b41e5edc9256e4f0cca1170ebadec.tar.xz
wireguard-openbsd-b4e5605a406b41e5edc9256e4f0cca1170ebadec.zip
Be more strict on state checking
-rw-r--r--src/if_wg.c21
-rw-r--r--src/mpq.h1
2 files changed, 17 insertions, 5 deletions
diff --git a/src/if_wg.c b/src/if_wg.c
index 992cc9f..11188a0 100644
--- a/src/if_wg.c
+++ b/src/if_wg.c
@@ -529,6 +529,7 @@ wg_peer_send_initiation(struct wg_peer *p)
tag->t_peer = p;
tag->t_type = WG_PKT_INITIATION;
+ tag->t_state = WG_PKT_STATE_NEW;
m->m_len = sizeof(struct wg_msg_initiation);
m_calchdrlen(m);
@@ -545,6 +546,7 @@ wg_peer_send_response(struct wg_peer *p)
tag->t_peer = p;
tag->t_type = WG_PKT_RESPONSE;
+ tag->t_state = WG_PKT_STATE_NEW;
m->m_len = sizeof(struct wg_msg_response);
m_calchdrlen(m);
@@ -561,6 +563,7 @@ wg_peer_send_keepalive(struct wg_peer *p)
tag->t_peer = p;
tag->t_type = WG_PKT_TRANSPORT;
+ tag->t_state = WG_PKT_STATE_NEW;
m->m_len = 0;
m_calchdrlen(m);
@@ -579,6 +582,9 @@ wg_encrypt_hs(struct mbuf *m)
struct wg_tag *tag = wg_mbuf_get_tag(m);
struct wg_peer *p = tag->t_peer;
+ if (tag->t_state != WG_PKT_STATE_NEW)
+ panic("not a new state packet: %d\n", tag->t_state);
+
switch (tag->t_type) {
case WG_PKT_INITIATION:
if (wg_handshake_initiation_ready(&p->p_hs) != WG_OK)
@@ -641,6 +647,9 @@ wg_encrypt(struct mbuf *m)
struct wg_tag *tag = wg_mbuf_get_tag(m);
struct wg_peer *p = tag->t_peer;
+ if (tag->t_state != WG_PKT_STATE_NEW && tag->t_state != WG_PKT_STATE_PASS)
+ panic("not a new/pass state packet: %d\n", tag->t_state);
+
em = m_clget(NULL, M_WAITOK, total_len);
msg = mtod(em, struct wg_msg_transport *);
m_copydata(m, 0, plain_len, msg->data);
@@ -912,8 +921,11 @@ wg_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
m->m_pkthdr.ph_family = sa->sa_family;
- if ((tag->t_peer = wg_softc_route_lookup(sc, m, true)) == NULL ||
- tag->t_peer->p_ip.sa.sa_family == AF_UNSPEC) {
+ tag->t_type = WG_PKT_TRANSPORT;
+ tag->t_state = WG_PKT_STATE_NEW;
+ tag->t_peer = wg_softc_route_lookup(sc, m, true);
+
+ if (tag->t_peer == NULL || tag->t_peer->p_ip.sa.sa_family == AF_UNSPEC) {
if (m->m_pkthdr.ph_family == AF_INET)
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
#ifdef INET6
@@ -927,9 +939,6 @@ wg_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
return ENETUNREACH;
}
- tag->t_type = WG_PKT_TRANSPORT;
- tag->t_state = WG_PKT_STATE_NEW;
-
if ((error = if_enqueue(ifp, m)) != 0) {
counters_inc(sc->sc_if.if_counters, ifc_oqdrops);
return error;
@@ -956,6 +965,7 @@ wg_input(void *_sc, struct mbuf *m, struct sockaddr *sa, int hlen)
goto free;
memcpy(&tag->t_ip.sa, sa, sa->sa_len);
+ tag->t_state = WG_PKT_STATE_NEW;
tag->t_type = wg_pkt_type(mtod(m, uint8_t *), m->m_pkthdr.len);
tag->t_sc = sc;
@@ -1040,6 +1050,7 @@ wg_output_deliver(struct mbuf *m)
}
sounlock(so, s);
} else {
+ /* Don't free as packet was queued for handshake */
DPRINTF(sc, "did not output packet\n");
}
}
diff --git a/src/mpq.h b/src/mpq.h
index 4ebeaa3..1629ccc 100644
--- a/src/mpq.h
+++ b/src/mpq.h
@@ -86,6 +86,7 @@ mpq_serialize_leave(struct mpq *mpq)
void
mpq_enqueue(struct mpq *mpq, struct mbuf *m)
{
+ /* TODO time based dropping of packets */
CLR(m->m_flags, M_LINK0);
mtx_enter(&mpq->mpq_mtx);
ml_enqueue(&mpq->mpq_list, m);