netstack: only return from open() once the socket connects
This commit is contained in:
parent
c8d6ce89f1
commit
fd80c0b227
|
@ -48,7 +48,7 @@ struct handle {
|
|||
};
|
||||
|
||||
|
||||
static void tcp_listen_callback(struct tcp_conn *c, void *arg) {
|
||||
static void tcp_conn_callback(struct tcp_conn *c, void *arg) {
|
||||
struct handle *h = arg;
|
||||
h->tcp.c = c;
|
||||
_sys_fs_respond(h->reqh, h, 0, 0);
|
||||
|
@ -181,11 +181,10 @@ static void fs_open(hid_t reqh, char *path, int flags) {
|
|||
port_s = strtok_r(NULL, "/", &save);
|
||||
if (port_s) {
|
||||
uint16_t port = strtol(port_s, NULL, 0);
|
||||
h = malloc(sizeof *h);
|
||||
memset(h, 0, sizeof *h);
|
||||
h = calloc(1, sizeof *h);
|
||||
h->type = H_TCP;
|
||||
h->reqh = reqh;
|
||||
tcp_listen(port, tcp_listen_callback, tcp_recv_callback, tcp_close_callback, h);
|
||||
tcp_listen(port, tcp_conn_callback, tcp_recv_callback, tcp_close_callback, h);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -198,19 +197,14 @@ static void fs_open(hid_t reqh, char *path, int flags) {
|
|||
port_s = strtok_r(NULL, "/", &save);
|
||||
if (port_s) {
|
||||
uint16_t port = strtol(port_s, NULL, 0);
|
||||
h = malloc(sizeof *h);
|
||||
memset(h, 0, sizeof *h);
|
||||
h = calloc(1, sizeof *h);
|
||||
h->type = H_TCP;
|
||||
h->tcp.c = tcpc_new((struct tcp){
|
||||
h->reqh = reqh;
|
||||
tcp_connect((struct tcp){
|
||||
.dst = port,
|
||||
.ip.dst = dstip,
|
||||
}, tcp_recv_callback, tcp_close_callback, h);
|
||||
if (h->tcp.c) {
|
||||
respond(h, 0);
|
||||
} else {
|
||||
free(h);
|
||||
respond(NULL, -1);
|
||||
}
|
||||
}, tcp_conn_callback, tcp_recv_callback, tcp_close_callback, h);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (strcmp(proto, "udp") == 0) {
|
||||
|
|
|
@ -97,8 +97,9 @@ void tcp_listen(
|
|||
void (*on_recv)(void *carg),
|
||||
void (*on_close)(void *carg),
|
||||
void *carg);
|
||||
struct tcp_conn *tcpc_new(
|
||||
void tcp_connect(
|
||||
struct tcp t,
|
||||
void (*on_conn)(struct tcp_conn *, void *carg),
|
||||
void (*on_recv)(void *carg),
|
||||
void (*on_close)(void *carg),
|
||||
void *carg);
|
||||
|
|
|
@ -108,8 +108,9 @@ void tcp_listen(
|
|||
c->rx = (ring_t){malloc(4096), 4096, 0, 0};
|
||||
conns_append(c);
|
||||
}
|
||||
struct tcp_conn *tcpc_new(
|
||||
void tcp_connect(
|
||||
struct tcp t,
|
||||
void (*on_conn)(struct tcp_conn *, void *carg),
|
||||
void (*on_recv)(void *carg),
|
||||
void (*on_close)(void *carg),
|
||||
void *carg)
|
||||
|
@ -126,11 +127,13 @@ struct tcp_conn *tcpc_new(
|
|||
if (arpcache_get(state.gateway, &c->rmac) < 0) {
|
||||
warnx("neither target nor gateway not in ARP cache, dropping");
|
||||
free(c);
|
||||
return NULL;
|
||||
on_close(carg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
c->state = SYN_SENT;
|
||||
c->on_conn = on_conn;
|
||||
c->on_recv = on_recv;
|
||||
c->on_close = on_close;
|
||||
c->carg = carg;
|
||||
|
@ -139,7 +142,6 @@ struct tcp_conn *tcpc_new(
|
|||
|
||||
tcpc_sendraw(c, FlagSYN, NULL, 0);
|
||||
c->lseq++;
|
||||
return c;
|
||||
}
|
||||
size_t tcpc_tryread(struct tcp_conn *c, void *buf, size_t len) {
|
||||
if (!buf) return ring_used(&c->rx);
|
||||
|
@ -198,52 +200,53 @@ void tcp_parse(const uint8_t *buf, size_t len, struct ipv4 ip) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (iter->rip == ip.src && iter->rport == srcport) {
|
||||
// TODO doesn't handle seq/ack overflows
|
||||
if (iter->state == SYN_SENT) {
|
||||
if (flags & FlagSYN) {
|
||||
iter->state = ESTABILISHED;
|
||||
iter->lack = seq + 1;
|
||||
tcpc_sendraw(iter, FlagACK, NULL, 0);
|
||||
return;
|
||||
} else {
|
||||
// TODO resend syn?
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (flags & FlagACK) {
|
||||
if (iter->rack < acknum)
|
||||
iter->rack = acknum;
|
||||
if (iter->state == LAST_ACK) {
|
||||
// TODO check if ack has correct number
|
||||
iter->state = CLOSED;
|
||||
tcpc_tryfree(iter);
|
||||
// TODO free (also after a timeout)
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (iter->lack != seq && iter->lack - 1 != seq) {
|
||||
warnx("remote seq jumped by %d", seq - iter->lack);
|
||||
if (iter->rip != ip.src || iter->rport != srcport) continue;
|
||||
|
||||
// TODO doesn't handle seq/ack overflows
|
||||
if (iter->state == SYN_SENT) {
|
||||
if (flags & FlagSYN) {
|
||||
iter->state = ESTABILISHED;
|
||||
iter->lack = seq + 1;
|
||||
tcpc_sendraw(iter, FlagACK, NULL, 0);
|
||||
if (iter->on_conn) iter->on_conn(iter, iter->carg);
|
||||
return;
|
||||
} else {
|
||||
// TODO resend syn?
|
||||
return;
|
||||
}
|
||||
// TODO check if overflows window size
|
||||
if (payloadlen) {
|
||||
iter->lack = seq + payloadlen;
|
||||
ring_put(&iter->rx, buf + hdrlen, payloadlen);
|
||||
if (iter->on_recv) iter->on_recv(iter->carg);
|
||||
tcpc_sendraw(iter, FlagACK, NULL, 0);
|
||||
}
|
||||
if (flags & FlagFIN) {
|
||||
// TODO should resend the packet until an ACK is received
|
||||
// TODO duplicated in tcpc_close
|
||||
tcpc_sendraw(iter, FlagFIN | FlagACK, NULL, 0);
|
||||
iter->state = LAST_ACK;
|
||||
if (iter->on_close) iter->on_close(iter->carg);
|
||||
}
|
||||
if (flags & FlagACK) {
|
||||
if (iter->rack < acknum)
|
||||
iter->rack = acknum;
|
||||
if (iter->state == LAST_ACK) {
|
||||
// TODO check if ack has correct number
|
||||
iter->state = CLOSED;
|
||||
tcpc_tryfree(iter);
|
||||
// TODO free (also after a timeout)
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (iter->lack != seq && iter->lack - 1 != seq) {
|
||||
warnx("remote seq jumped by %d", seq - iter->lack);
|
||||
tcpc_sendraw(iter, FlagACK, NULL, 0);
|
||||
return;
|
||||
}
|
||||
// TODO check if overflows window size
|
||||
if (payloadlen) {
|
||||
iter->lack = seq + payloadlen;
|
||||
ring_put(&iter->rx, buf + hdrlen, payloadlen);
|
||||
if (iter->on_recv) iter->on_recv(iter->carg);
|
||||
tcpc_sendraw(iter, FlagACK, NULL, 0);
|
||||
}
|
||||
if (flags & FlagFIN) {
|
||||
// TODO should resend the packet until an ACK is received
|
||||
// TODO duplicated in tcpc_close
|
||||
tcpc_sendraw(iter, FlagFIN | FlagACK, NULL, 0);
|
||||
iter->state = LAST_ACK;
|
||||
if (iter->on_close) iter->on_close(iter->carg);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ((flags & FlagRST) == 0) {
|
||||
|
|
|
@ -70,7 +70,6 @@ fs_open(char *path, int flags) {
|
|||
* 0x01 one authentication method:
|
||||
* 0x00 no auth */
|
||||
char buf[512];
|
||||
sleep(1); // TODO fix the netstack
|
||||
write(h->sock, "\x05\x01\x00", 3);
|
||||
|
||||
errno = EGENERIC;
|
||||
|
|
Loading…
Reference in New Issue