commit 0640b55566b66eb28c4c16f22c10e47b58207394 from: Omar Polo date: Fri May 27 14:20:39 2022 UTC 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)