commit - 612d2546ec8bfffdcab59f3a7069c6bf664a0ee4
commit + 0640b55566b66eb28c4c16f22c10e47b58207394
blob - ca22fed6dffa21ab2a2c680563eb9455af40df56
blob + a9966d5ca5647879cf01340f26d4281496f2d80d
--- net.c
+++ net.c
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*);
}
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)