Commit Diff
Diff:
612d2546ec8bfffdcab59f3a7069c6bf664a0ee4
0640b55566b66eb28c4c16f22c10e47b58207394
Commit:
0640b55566b66eb28c4c16f22c10e47b58207394
Tree:
48a64bb9425faa438ba855aed4fea76e515bc6ce
Author:
Omar Polo <op@omarpolo.com>
Date:
Fri May 27 14:20:39 2022 UTC
Message:
re-group the handling of imsgs

while here also do more validation in IMSG_GET_RAW and add a missing
NULL check in the return type of req_by_id in the IMSG_CERT_STATUS.
commit - 612d2546ec8bfffdcab59f3a7069c6bf664a0ee4
commit + 0640b55566b66eb28c4c16f22c10e47b58207394
blob - ca22fed6dffa21ab2a2c680563eb9455af40df56
blob + a9966d5ca5647879cf01340f26d4281496f2d80d
--- net.c
+++ net.c
@@ -88,25 +88,12 @@ static void net_read(struct bufferevent *, void *);
static void net_write(struct bufferevent *, void *);
static void net_error(struct bufferevent *, short, void *);
-static void handle_get_raw(struct imsg *, size_t);
-static void handle_cert_status(struct imsg*, size_t);
-static void handle_proceed(struct imsg*, size_t);
-static void handle_stop(struct imsg*, size_t);
-static void handle_quit(struct imsg*, size_t);
static void handle_dispatch_imsg(int, short, void*);
static int net_send_ui(int, uint32_t, const void *, uint16_t);
/* TODO: making this customizable */
struct timeval timeout_for_handshake = { 5, 0 };
-
-static imsg_handlerfn *handlers[] = {
- [IMSG_GET_RAW] = handle_get_raw,
- [IMSG_CERT_STATUS] = handle_cert_status,
- [IMSG_PROCEED] = handle_proceed,
- [IMSG_STOP] = handle_stop,
- [IMSG_QUIT] = handle_quit,
-};
typedef void (*statefn)(int, short, void*);
@@ -649,87 +636,102 @@ net_error(struct bufferevent *bev, short error, void *
}
static void
-handle_get_raw(struct imsg *imsg, size_t datalen)
+handle_dispatch_imsg(int fd, short event, void *d)
{
+ struct imsgev *iev = d;
+ struct imsgbuf *ibuf = &iev->ibuf;
+ struct imsg imsg;
struct req *req;
struct get_req *r;
-
- r = imsg->data;
-
- if (datalen != sizeof(*r))
- die();
+ size_t datalen;
+ ssize_t n;
+ int certok;
- if ((req = calloc(1, sizeof(*req))) == NULL)
- die();
+ if (event & EV_READ) {
+ if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
+ err(1, "imsg_read");
+ if (n == 0)
+ err(1, "connection closed");
+ }
+ if (event & EV_WRITE) {
+ if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
+ err(1, "msgbuf_write");
+ if (n == 0)
+ err(1, "connection closed");
+ }
- req->id = imsg->hdr.peerid;
- TAILQ_INSERT_HEAD(&reqhead, req, reqs);
-
- strlcpy(req->url.host, r->host, sizeof(req->url.host));
- strlcpy(req->url.port, r->port, sizeof(req->url.port));
+ for (;;) {
+ if ((n = imsg_get(ibuf, &imsg)) == -1)
+ err(1, "imsg_get");
+ if (n == 0)
+ break;
+ datalen = IMSG_DATA_SIZE(imsg);
+ switch (imsg.hdr.type) {
+ case IMSG_GET_RAW:
+ r = imsg.data;
+ if (datalen != sizeof(*r) ||
+ r->host[sizeof(r->host) - 1] != '\0' ||
+ r->port[sizeof(r->port) - 1] != '\0' ||
+ r->req[sizeof(r->req) - 1] != '\0')
+ die();
+ if (r->proto != PROTO_FINGER &&
+ r->proto != PROTO_GEMINI &&
+ r->proto != PROTO_GOPHER)
+ die();
- strlcpy(req->req, r->req, sizeof(req->req));
- req->len = strlen(r->req);
+ if ((req = calloc(1, sizeof(*req))) == NULL)
+ die();
- req->proto = r->proto;
+ req->id = imsg.hdr.peerid;
+ TAILQ_INSERT_HEAD(&reqhead, req, reqs);
- conn_towards(req);
-}
+ strlcpy(req->url.host, r->host, sizeof(req->url.host));
+ strlcpy(req->url.port, r->port, sizeof(req->url.port));
+ req->len = strlcpy(req->req, r->req, sizeof(req->req));
+ req->proto = r->proto;
+ conn_towards(req);
+ break;
+
+ case IMSG_CERT_STATUS:
+ if ((req = req_by_id(imsg.hdr.peerid)) == NULL)
+ break;
+
+ if (datalen != sizeof(certok))
+ die();
+ memcpy(&certok, imsg.data, sizeof(certok));
+ if (certok)
+ net_ready(req);
+ else
+ close_conn(0, 0, req);
+ break;
-static void
-handle_cert_status(struct imsg *imsg, size_t datalen)
-{
- struct req *req;
- int is_ok;
+ case IMSG_PROCEED:
+ if ((req = req_by_id(imsg.hdr.peerid)) == NULL)
+ break;
+ bufferevent_enable(req->bev, EV_READ);
+ break;
- req = req_by_id(imsg->hdr.peerid);
+ case IMSG_STOP:
+ if ((req = req_by_id(imsg.hdr.peerid)) == NULL)
+ break;
+ close_conn(0, 0, req);
+ break;
- if (datalen < sizeof(is_ok))
- die();
- memcpy(&is_ok, imsg->data, sizeof(is_ok));
+ case IMSG_QUIT:
+ event_loopbreak();
+ imsg_free(&imsg);
+ return;
- if (is_ok)
- net_ready(req);
- else
- close_conn(0, 0, req);
-}
+ default:
+ errx(1, "got unknown imsg %d", imsg.hdr.type);
+ }
-static void
-handle_proceed(struct imsg *imsg, size_t datalen)
-{
- struct req *req;
+ imsg_free(&imsg);
+ }
- if ((req = req_by_id(imsg->hdr.peerid)) == NULL)
- return;
-
- bufferevent_enable(req->bev, EV_READ);
+ imsg_event_add(iev);
}
-static void
-handle_stop(struct imsg *imsg, size_t datalen)
-{
- struct req *req;
-
- if ((req = req_by_id(imsg->hdr.peerid)) == NULL)
- return;
- close_conn(0, 0, req);
-}
-
-static void
-handle_quit(struct imsg *imsg, size_t datalen)
-{
- event_loopbreak();
-}
-
-static void
-handle_dispatch_imsg(int fd, short ev, void *d)
-{
- struct imsgev *iev = d;
-
- if (dispatch_imsg(iev, ev, handlers, sizeof(handlers)) == -1)
- err(1, "connection closed");
-}
-
static int
net_send_ui(int type, uint32_t peerid, const void *data,
uint16_t datalen)
Omar Polo