uloop_end();
}
-static void pex_recv(struct pex_hdr *hdr, struct sockaddr_in6 *addr)
+static void pex_recv(void *msg, size_t msg_len, struct sockaddr_in6 *addr)
{
- struct pex_ext_hdr *ehdr = (void *)(hdr + 1);
- void *data = (void *)(ehdr + 1);
- uint32_t len = be32_to_cpu(hdr->len);
- uint64_t *msg_req_id = data;
+ struct pex_hdr *hdr;
+ struct pex_ext_hdr *ehdr;
+ uint64_t *msg_req_id;
+ void *data;
+
+ hdr = pex_rx_accept(msg, msg_len, true);
+ if (!hdr)
+ return;
+
+ ehdr = (void *)(hdr + 1);
+ data = (void *)(ehdr + 1);
+ msg_req_id = data;
if (hdr->version != 0)
return;
if (cmd != CMD_UPLOAD)
break;
- pex_handle_update_request(addr, hdr->id, data, len);
+ pex_handle_update_request(addr, hdr->id, data, hdr->len);
break;
case PEX_MSG_UPDATE_RESPONSE:
case PEX_MSG_UPDATE_RESPONSE_DATA:
case PEX_MSG_UPDATE_RESPONSE_NO_DATA:
- if (len < sizeof(*msg_req_id) || *msg_req_id != req_id)
+ if (hdr->len < sizeof(*msg_req_id) || *msg_req_id != req_id)
break;
if (cmd == CMD_DOWNLOAD &&
{
static struct sockaddr_in6 sin6;
static char buf[PEX_RX_BUF_SIZE];
- struct pex_hdr *hdr = (struct pex_hdr *)buf;
ssize_t len;
while (1) {
}
}
- if (len < sizeof(*hdr) + sizeof(struct pex_ext_hdr))
- continue;
-
- hdr->len = ntohs(hdr->len);
- if (len - sizeof(hdr) - sizeof(struct pex_ext_hdr) < hdr->len)
- continue;
-
- pex_recv_cb(hdr, &sin6);
+ pex_recv_cb(buf, len, &sin6);
}
}
return NULL;
}
+struct pex_hdr *pex_rx_accept(void *data, size_t len, bool ext)
+{
+ struct pex_hdr *hdr = data;
+ uint16_t hdr_len;
+ size_t min_size;
+
+ min_size = sizeof(*hdr);
+ if (ext)
+ min_size += sizeof(struct pex_ext_hdr);
+
+ if (len < min_size)
+ return NULL;
+
+ hdr_len = ntohs(hdr->len);
+ if (len < min_size + hdr_len)
+ return NULL;
+
+ hdr->len = hdr_len;
+
+ return hdr;
+}
+
static void
pex_gc_cb(struct uloop_timeout *t)
{
int timeout;
};
-typedef void (*pex_recv_cb_t)(struct pex_hdr *hdr, struct sockaddr_in6 *addr);
+struct pex_hdr *pex_rx_accept(void *data, size_t len, bool ext);
+
+typedef void (*pex_recv_cb_t)(void *data, size_t len, struct sockaddr_in6 *addr);
typedef void (*pex_recv_control_cb_t)(struct pex_msg_local_control *msg, int len);
int pex_open(void *addr, size_t addr_len, pex_recv_cb_t cb, bool server);
if (!len)
continue;
- if (len < sizeof(*hdr))
- continue;
-
- hdr->len = ntohs(hdr->len);
- if (len - sizeof(hdr) < hdr->len)
+ hdr = pex_rx_accept(buf, len, false);
+ if (!hdr)
continue;
peer = pex_msg_peer(net, hdr->id);
}
static void
-global_pex_recv(struct pex_hdr *hdr, struct sockaddr_in6 *addr)
+global_pex_recv(void *msg, size_t msg_len, struct sockaddr_in6 *addr)
{
- struct pex_ext_hdr *ehdr = (void *)(hdr + 1);
+ struct pex_hdr *hdr;
+ struct pex_ext_hdr *ehdr;
struct network_peer *peer;
struct network *net;
- void *data = (void *)(ehdr + 1);
char buf[INET6_ADDRSTRLEN];
+ void *data;
int addr_len;
+ hdr = pex_rx_accept(msg, msg_len, true);
+ if (!hdr)
+ return;
+
+ ehdr = (void *)(hdr + 1);
+ data = (void *)(ehdr + 1);
+
if (hdr->version != 0)
return;