summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cmd/netstack/fs.c22
-rw-r--r--src/cmd/netstack/proto.h3
-rw-r--r--src/cmd/netstack/tcp.c87
-rw-r--r--src/cmd/socksfs/socksfs.c1
4 files changed, 55 insertions, 58 deletions
diff --git a/src/cmd/netstack/fs.c b/src/cmd/netstack/fs.c
index 92681ba..802b984 100644
--- a/src/cmd/netstack/fs.c
+++ b/src/cmd/netstack/fs.c
@@ -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) {
diff --git a/src/cmd/netstack/proto.h b/src/cmd/netstack/proto.h
index 8ea11ac..701cb59 100644
--- a/src/cmd/netstack/proto.h
+++ b/src/cmd/netstack/proto.h
@@ -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);
diff --git a/src/cmd/netstack/tcp.c b/src/cmd/netstack/tcp.c
index cbe2c14..c0839f2 100644
--- a/src/cmd/netstack/tcp.c
+++ b/src/cmd/netstack/tcp.c
@@ -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) {
diff --git a/src/cmd/socksfs/socksfs.c b/src/cmd/socksfs/socksfs.c
index 4f530f4..9469d0c 100644
--- a/src/cmd/socksfs/socksfs.c
+++ b/src/cmd/socksfs/socksfs.c
@@ -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;