commit - 7713cc5e4f5544e81909670d592e89526ed86c9b
commit + 3448a19afa20edfa1069b2d793abcda5a9006565
blob - 0bc48fac834b679822e3314db38590b9da8f3575
blob + c2bf744e16922aec4500424898af4499c5240308
--- gotd/session.c
+++ gotd/session.c
char *packfile_path;
char *packidx_path;
int nref_updates;
+ int accept_flush_pkt;
} gotd_session_client;
void gotd_session_sighdlr(int sig, short event, void *arg);
break;
if (!client->is_writing) {
client->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;
+ client->accept_flush_pkt = 1;
log_debug("uid %d: expecting ref-update-lines",
client->euid);
} else
err = ensure_client_is_reading(client);
if (err)
break;
+ client->accept_flush_pkt = 1;
err = forward_want(client, &imsg);
break;
case GOTD_IMSG_REF_UPDATE:
if (err)
break;
client->state = GOTD_STATE_EXPECT_MORE_REF_UPDATES;
+ client->accept_flush_pkt = 1;
break;
case GOTD_IMSG_HAVE:
if (client->state != GOTD_STATE_EXPECT_HAVE) {
err = forward_have(client, &imsg);
if (err)
break;
+ client->accept_flush_pkt = 1;
break;
case GOTD_IMSG_FLUSH:
if (client->state == GOTD_STATE_EXPECT_WANT ||
if (err)
break;
} else if (client->state != GOTD_STATE_EXPECT_DONE) {
+ err = got_error_msg(GOT_ERR_BAD_REQUEST,
+ "unexpected flush-pkt received");
+ break;
+ }
+ if (!client->accept_flush_pkt) {
err = got_error_msg(GOT_ERR_BAD_REQUEST,
"unexpected flush-pkt received");
break;
}
+
+ /*
+ * Accept just one flush packet at a time.
+ * Future client state transitions will set this flag
+ * again if another flush packet is expected.
+ */
+ client->accept_flush_pkt = 0;
+
log_debug("received flush-pkt from uid %d",
client->euid);
if (client->state == GOTD_STATE_EXPECT_WANT) {
client->euid);
} else if (client->state == GOTD_STATE_EXPECT_HAVE) {
client->state = GOTD_STATE_EXPECT_DONE;
+ client->accept_flush_pkt = 1;
log_debug("uid %d: expecting 'done'",
client->euid);
} else if (client->state ==
if (err)
break;
client->state = GOTD_STATE_DONE;
+ client->accept_flush_pkt = 1;
err = send_packfile(client);
break;
default:
gotd_session_client.fd = -1;
gotd_session_client.nref_updates = -1;
gotd_session_client.delta_cache_fd = -1;
+ gotd_session_client.accept_flush_pkt = 1;
imsg_init(&gotd_session.parent_iev.ibuf, GOTD_FILENO_MSG_PIPE);
gotd_session.parent_iev.handler = session_dispatch;