commit 818f96befdf8fe0b407ab7fec236b71d57bc3597 from: Stefan Sperling date: Thu Mar 21 09:45:11 2024 UTC track session state in struct gotd_session instead of got_session_client Eventually, I would like to disconnect clients before notifications are generated. This change helps pave the way towards this goal. commit - 09486e84b6094ffcb4dca9ecd2dea72a982a1fa9 commit + 818f96befdf8fe0b407ab7fec236b71d57bc3597 blob - 163f482824dd1bbb39949c76de672eb8682b553a blob + 1565134cdf2580a8d8ad95a1e62986080575bce4 --- gotd/session.c +++ gotd/session.c @@ -74,10 +74,10 @@ static struct gotd_session { struct gotd_imsgev notifier_iev; struct timeval request_timeout; enum gotd_procid proc_id; + enum gotd_session_state state; } gotd_session; static struct gotd_session_client { - enum gotd_session_state state; int is_writing; struct gotd_client_capability *capabilities; size_t ncapa_alloc; @@ -808,7 +808,7 @@ done: send_refs_updated(client); notif = STAILQ_FIRST(¬ifications); if (notif) { - client->state = GOTD_STATE_NOTIFY; + gotd_session.state = GOTD_STATE_NOTIFY; err = request_notification(notif); if (err) { log_warn("could not send notification: " @@ -1376,7 +1376,8 @@ session_dispatch_client(int fd, short events, void *ar if (err->code == GOT_ERR_PRIVSEP_READ) err = NULL; else if (err->code == GOT_ERR_EOF && - client->state == GOTD_STATE_EXPECT_CAPABILITIES) { + gotd_session.state == + GOTD_STATE_EXPECT_CAPABILITIES) { /* * The client has closed its socket before * sending its capability announcement. @@ -1393,7 +1394,8 @@ session_dispatch_client(int fd, short events, void *ar switch (imsg.hdr.type) { case GOTD_IMSG_CAPABILITIES: - if (client->state != GOTD_STATE_EXPECT_CAPABILITIES) { + if (gotd_session.state != + GOTD_STATE_EXPECT_CAPABILITIES) { err = got_error_msg(GOT_ERR_BAD_REQUEST, "unexpected capabilities received"); break; @@ -1403,7 +1405,7 @@ session_dispatch_client(int fd, short events, void *ar err = recv_capabilities(client, &imsg); break; case GOTD_IMSG_CAPABILITY: - if (client->state != GOTD_STATE_EXPECT_CAPABILITIES) { + if (gotd_session.state != GOTD_STATE_EXPECT_CAPABILITIES) { err = got_error_msg(GOT_ERR_BAD_REQUEST, "unexpected capability received"); break; @@ -1412,12 +1414,12 @@ session_dispatch_client(int fd, short events, void *ar if (err || client->ncapabilities < client->ncapa_alloc) break; if (!client->is_writing) { - client->state = GOTD_STATE_EXPECT_WANT; + gotd_session.state = GOTD_STATE_EXPECT_WANT; client->accept_flush_pkt = 1; log_debug("uid %d: expecting want-lines", client->euid); } else if (client->is_writing) { - client->state = GOTD_STATE_EXPECT_REF_UPDATE; + gotd_session.state = GOTD_STATE_EXPECT_REF_UPDATE; client->accept_flush_pkt = 1; log_debug("uid %d: expecting ref-update-lines", client->euid); @@ -1426,7 +1428,7 @@ session_dispatch_client(int fd, short events, void *ar client->euid); break; case GOTD_IMSG_WANT: - if (client->state != GOTD_STATE_EXPECT_WANT) { + if (gotd_session.state != GOTD_STATE_EXPECT_WANT) { err = got_error_msg(GOT_ERR_BAD_REQUEST, "unexpected want-line received"); break; @@ -1440,8 +1442,8 @@ session_dispatch_client(int fd, short events, void *ar err = forward_want(client, &imsg); break; case GOTD_IMSG_REF_UPDATE: - if (client->state != GOTD_STATE_EXPECT_REF_UPDATE && - client->state != + if (gotd_session.state != GOTD_STATE_EXPECT_REF_UPDATE && + gotd_session.state != GOTD_STATE_EXPECT_MORE_REF_UPDATES) { err = got_error_msg(GOT_ERR_BAD_REQUEST, "unexpected ref-update-line received"); @@ -1455,11 +1457,11 @@ session_dispatch_client(int fd, short events, void *ar err = forward_ref_update(client, &imsg); if (err) break; - client->state = GOTD_STATE_EXPECT_MORE_REF_UPDATES; + gotd_session.state = GOTD_STATE_EXPECT_MORE_REF_UPDATES; client->accept_flush_pkt = 1; break; case GOTD_IMSG_HAVE: - if (client->state != GOTD_STATE_EXPECT_HAVE) { + if (gotd_session.state != GOTD_STATE_EXPECT_HAVE) { err = got_error_msg(GOT_ERR_BAD_REQUEST, "unexpected have-line received"); break; @@ -1475,17 +1477,17 @@ session_dispatch_client(int fd, short events, void *ar client->accept_flush_pkt = 1; break; case GOTD_IMSG_FLUSH: - if (client->state == GOTD_STATE_EXPECT_WANT || - client->state == GOTD_STATE_EXPECT_HAVE) { + if (gotd_session.state == GOTD_STATE_EXPECT_WANT || + gotd_session.state == GOTD_STATE_EXPECT_HAVE) { err = ensure_client_is_reading(client); if (err) break; - } else if (client->state == + } else if (gotd_session.state == GOTD_STATE_EXPECT_MORE_REF_UPDATES) { err = ensure_client_is_writing(client); if (err) break; - } else if (client->state != GOTD_STATE_EXPECT_DONE) { + } else if (gotd_session.state != GOTD_STATE_EXPECT_DONE) { err = got_error_msg(GOT_ERR_BAD_REQUEST, "unexpected flush-pkt received"); break; @@ -1505,22 +1507,22 @@ session_dispatch_client(int fd, short events, void *ar log_debug("received flush-pkt from uid %d", client->euid); - if (client->state == GOTD_STATE_EXPECT_WANT) { - client->state = GOTD_STATE_EXPECT_HAVE; + if (gotd_session.state == GOTD_STATE_EXPECT_WANT) { + gotd_session.state = GOTD_STATE_EXPECT_HAVE; log_debug("uid %d: expecting have-lines", client->euid); - } else if (client->state == GOTD_STATE_EXPECT_HAVE) { - client->state = GOTD_STATE_EXPECT_DONE; + } else if (gotd_session.state == GOTD_STATE_EXPECT_HAVE) { + gotd_session.state = GOTD_STATE_EXPECT_DONE; client->accept_flush_pkt = 1; log_debug("uid %d: expecting 'done'", client->euid); - } else if (client->state == + } else if (gotd_session.state == GOTD_STATE_EXPECT_MORE_REF_UPDATES) { - client->state = GOTD_STATE_EXPECT_PACKFILE; + gotd_session.state = GOTD_STATE_EXPECT_PACKFILE; log_debug("uid %d: expecting packfile", client->euid); err = recv_packfile(client); - } else if (client->state != GOTD_STATE_EXPECT_DONE) { + } else if (gotd_session.state != GOTD_STATE_EXPECT_DONE) { /* should not happen, see above */ err = got_error_msg(GOT_ERR_BAD_REQUEST, "unexpected client state"); @@ -1528,8 +1530,8 @@ session_dispatch_client(int fd, short events, void *ar } break; case GOTD_IMSG_DONE: - if (client->state != GOTD_STATE_EXPECT_HAVE && - client->state != GOTD_STATE_EXPECT_DONE) { + if (gotd_session.state != GOTD_STATE_EXPECT_HAVE && + gotd_session.state != GOTD_STATE_EXPECT_DONE) { err = got_error_msg(GOT_ERR_BAD_REQUEST, "unexpected flush-pkt received"); break; @@ -1538,7 +1540,7 @@ session_dispatch_client(int fd, short events, void *ar err = ensure_client_is_reading(client); if (err) break; - client->state = GOTD_STATE_DONE; + gotd_session.state = GOTD_STATE_DONE; client->accept_flush_pkt = 1; err = send_packfile(client); break; @@ -1553,7 +1555,7 @@ session_dispatch_client(int fd, short events, void *ar if (err) { if (err->code != GOT_ERR_EOF || - client->state != GOTD_STATE_EXPECT_PACKFILE) + gotd_session.state != GOTD_STATE_EXPECT_PACKFILE) disconnect_on_error(client, err); } else { gotd_imsg_event_add(iev); @@ -1570,7 +1572,7 @@ list_refs_request(void) struct gotd_imsg_list_refs_internal ilref; int fd; - if (client->state != GOTD_STATE_EXPECT_LIST_REFS) + if (gotd_session.state != GOTD_STATE_EXPECT_LIST_REFS) return got_error(GOT_ERR_PRIVSEP_MSG); memset(&ilref, 0, sizeof(ilref)); @@ -1587,7 +1589,7 @@ list_refs_request(void) return err; } - client->state = GOTD_STATE_EXPECT_CAPABILITIES; + gotd_session.state = GOTD_STATE_EXPECT_CAPABILITIES; log_debug("uid %d: expecting capabilities", client->euid); return NULL; } @@ -1599,7 +1601,7 @@ recv_connect(struct imsg *imsg) struct gotd_imsg_connect iconnect; size_t datalen; - if (client->state != GOTD_STATE_EXPECT_LIST_REFS) + if (gotd_session.state != GOTD_STATE_EXPECT_LIST_REFS) return got_error(GOT_ERR_PRIVSEP_MSG); datalen = imsg->hdr.len - IMSG_HEADER_SIZE; @@ -1674,7 +1676,7 @@ session_dispatch_notifier(int fd, short event, void *a switch (imsg.hdr.type) { case GOTD_IMSG_NOTIFICATION_SENT: - if (client->state != GOTD_STATE_NOTIFY) { + if (gotd_session.state != GOTD_STATE_NOTIFY) { log_warn("unexpected imsg %d", imsg.hdr.type); break; } @@ -1717,7 +1719,7 @@ recv_notifier(struct imsg *imsg) size_t datalen; int fd; - if (client->state != GOTD_STATE_EXPECT_LIST_REFS) + if (gotd_session.state != GOTD_STATE_EXPECT_LIST_REFS) return got_error(GOT_ERR_PRIVSEP_MSG); /* We should already have received a pipe to the listener. */ @@ -1751,7 +1753,7 @@ recv_repo_child(struct imsg *imsg) size_t datalen; int fd; - if (client->state != GOTD_STATE_EXPECT_LIST_REFS) + if (gotd_session.state != GOTD_STATE_EXPECT_LIST_REFS) return got_error(GOT_ERR_PRIVSEP_MSG); /* We should already have received a pipe to the listener. */ @@ -1923,7 +1925,8 @@ session_main(const char *title, const char *repo_path, signal_add(&evsighup, NULL); signal_add(&evsigusr1, NULL); - gotd_session_client.state = GOTD_STATE_EXPECT_LIST_REFS; + gotd_session.state = GOTD_STATE_EXPECT_LIST_REFS; + gotd_session_client.fd = -1; gotd_session_client.nref_updates = -1; gotd_session_client.delta_cache_fd = -1;