Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion elks/include/linuxmt/tcpdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ struct tdb_return_data {
struct tdb_accept_ret {
char type;
int ret_value;
struct socket *sock;
struct socket *sock; /* listen socket, for wake_up */
struct socket *newsock; /* accepted socket, gets addr filled in */
__u32 addr_ip;
__u16 addr_port;
__u32 locaddr;
Expand Down
44 changes: 29 additions & 15 deletions elks/net/ipv4/af_inet.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ static sem_t rwlock; /* global inet_read/write semaphore*/

int inet_process_tcpdev(register char *buf, int len)
{
register struct socket *sock;
struct socket *sock, *newsock;
struct tdb_accept_ret *ar;

sock = ((struct tdb_return_data *)buf)->sock;
debug_net("INET(%P) process_tcpdev sock %x type %d wait %x\n",
Expand Down Expand Up @@ -77,8 +78,27 @@ int inet_process_tcpdev(register char *buf, int len)
wake_up(sock->wait);
break;

case TDT_RETURN:
case TDT_ACCEPT:
/*
* Copy accept result into newsock so we can auto-release bufin_sem
* immediately and not depend on the woken process running fast enough
* to consume tdin_buf before ktcp writes its next reply.
*/
ar = (struct tdb_accept_ret *)buf;
newsock = ar->newsock;
if (newsock) {
newsock->remaddr = ar->addr_ip;
newsock->remport = ar->addr_port;
newsock->localaddr = ar->locaddr;
newsock->localport = ar->locport;
newsock->retval = ar->ret_value;
newsock->flags |= SF_CONNECT;
}
tcpdev_clear_data_avail();
wake_up(sock->wait);
break;

case TDT_RETURN:
case TDT_BIND:
debug_net("INET(%P) retval %d bufin %d\n",
((struct tdb_return_data *)buf)->ret_value, bufin_sem);
Expand Down Expand Up @@ -227,6 +247,7 @@ static int inet_accept(register struct socket *sock, struct socket *newsock, int
int ret;

debug_tune("INET(%P) accept wait sock %x newsock %x\n", sock, newsock);
newsock->flags &= ~SF_CONNECT; /* cleared until reply arrives */
cmd = (struct tdb_accept *)get_tdout_buf();
cmd->cmd = TDC_ACCEPT;
cmd->sock = sock;
Expand All @@ -235,25 +256,18 @@ static int inet_accept(register struct socket *sock, struct socket *newsock, int

tcpdev_inetwrite(cmd, sizeof(struct tdb_accept));

/* Sleep until tcpdev has news */
do { /* always sleep once to prevent accept race condition #1082 */

/* Sleep until inet_process_tcpdev stores the reply into newsock */
do {
/* Always sleep once to prevent accept race condition #1082 (unneeded anymore?) */
interruptible_sleep_on(sock->wait);
//interruptible_sleep_on(newsock->wait);

if (current->signal) {
debug_net("INET(%P) accept RESTARTSYS bufin %d\n", bufin_sem);
debug_net("INET(%P) accept RESTARTSYS\n");
return -ERESTARTSYS;
}
} while (bufin_sem == 0);
} while (!(newsock->flags & SF_CONNECT));

debug_tune("INET(%P) accepted sock %x newsock %x\n", sock, newsock);
newsock->remaddr = ((struct tdb_accept_ret *)tdin_buf)->addr_ip;
newsock->remport = ((struct tdb_accept_ret *)tdin_buf)->addr_port;
newsock->localaddr = ((struct tdb_accept_ret *)tdin_buf)->locaddr;
newsock->localport = ((struct tdb_accept_ret *)tdin_buf)->locport;
ret = ((struct tdb_accept_ret *)tdin_buf)->ret_value;
tcpdev_clear_data_avail();
ret = newsock->retval;
if (ret >= 0) {
newsock->state = SS_CONNECTED;
ret = 0;
Expand Down
2 changes: 1 addition & 1 deletion elkscmd/ktcp/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
/* turn these on for ELKS debugging*/
#define USE_DEBUG_EVENT 1 /* use CTRLP to toggle debug output*/
#define DEBUG_STARTDEF 0 /* default startup debug display*/
#define DEBUG_TCP 0 /* TCP ops*/
#define DEBUG_TCP 1 /* TCP ops*/
#define DEBUG_TCPPKT 0 /* TCP packets info*/
#define DEBUG_TCPDATA 1 /* TCP packet data display*/
#define DEBUG_CWND 0 /* TCP congestion control*/
Expand Down
8 changes: 6 additions & 2 deletions elkscmd/ktcp/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ static void tcp_established(struct iptcp_s *iptcp, struct tcpcb_s *cb)
in_ntoa(cb->remaddr), ntohs(h->sport), ntohs(h->dport));
#endif
rmv_all_retrans_cb(cb);
if (cb->bytes_to_push > 0)
tcpcb_need_push--;

if (cb->state == TS_CLOSE_WAIT) {
//cbs_in_user_timeout--; /* CLOSE_WAIT does not timeout */
Expand Down Expand Up @@ -354,8 +356,10 @@ static void tcp_synrecv(struct iptcp_s *iptcp, struct tcpcb_s *cb)
{
struct tcphdr_s *h = iptcp->tcph;

if (h->flags & TF_RST)
cb->state = TS_LISTEN; /* FIXME: not valid, should dealloc extra CB*/
if (h->flags & TF_RST) {
rmv_all_retrans_cb(cb);
tcpcb_remove_cb(cb);
}
else if ((h->flags & TF_ACK) == 0)
debug_tcp("tcp: NO ACK IN SYNRECV\n");
else {
Expand Down
36 changes: 19 additions & 17 deletions elkscmd/ktcp/tcpdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ static void tcpdev_bind(void)
struct tcpcb_list_s *n2 = tcpcb_check_port(port);
if (n2) { /* port already bound */
if (!db->reuse_addr) { /* no SO_REUSEADDR on socket */
debug_tune("tcp: port %u already bound, rejecting (use SO_REUSEADDR?)\n", port);
debug_tune("tcp: port %u already bound, rejecting (use SO_REUSEADDR?)\n",
port);
reject:
tcpcb_remove(n);
retval_to_sock(db->sock, -EADDRINUSE);
Expand All @@ -104,11 +105,11 @@ static void tcpdev_bind(void)

/* remove TCB control block on SO_REUSEADDR to save heap space */
if (n2->tcpcb.state == TS_TIME_WAIT) {
LEAVE_TIME_WAIT(&n2->tcpcb); /* entered via FIN_WAIT_2 state on FIN rcvd*/
LEAVE_TIME_WAIT(&n2->tcpcb); /* entered via FIN_WAIT_2 state on FIN rcvd*/
tcpcb_remove(n2);
debug_tune("tcp: port %u REUSED, freeing previous socket in time_wait\n", port);
debug_tune("tcp: port %u reused, freeing socket in time_wait\n", port);
} else {
printf("tcp: port %u NOT reused, previous socket in state %d\n",
debug_tune("tcp: port %u not reused, socket state %d\n",
port, n2->tcpcb.state);
goto reject;
}
Expand Down Expand Up @@ -168,8 +169,8 @@ static void tcpdev_accept(void)

accept_ret.type = TDT_ACCEPT;
accept_ret.ret_value = 0;
accept_ret.sock = sock; /* report back listen socket*/
//accept_ret.sock = db->newsock; /* report back new socket*/
accept_ret.sock = sock; /* report back listen socket, for wake_up */
accept_ret.newsock = db->newsock; /* kernel stores addr into this sock */
accept_ret.addr_ip = cb->remaddr;
accept_ret.addr_port = htons(cb->remport);
accept_ret.locaddr = cb->localaddr;
Expand Down Expand Up @@ -201,8 +202,8 @@ void tcpdev_notify_accept(struct tcpcb_s *cb)

accept_ret.type = TDT_ACCEPT;
accept_ret.ret_value = 0;
accept_ret.sock = listencb->sock; /* report back listen socket*/
//accept_ret.sock = listencb->newsock; /* report back new socket*/
accept_ret.sock = listencb->sock; /* report back listen socket, for wake_up */
accept_ret.newsock = listencb->newsock; /* kernel stores addr into this sock */
accept_ret.addr_ip = cb->remaddr;
accept_ret.addr_port = htons(cb->remport);
accept_ret.locaddr = cb->localaddr;
Expand All @@ -226,7 +227,8 @@ static void tcpdev_connect(void)

n = tcpcb_find_by_sock(db->sock);
if (!n || n->tcpcb.state != TS_CLOSED) {
debug_tcp("tcp: panic in connect\n");
debug_tcp("tcp: connect on socket w/no CB\n");
retval_to_sock(db->sock, -ECONNREFUSED);
return;
}

Expand Down Expand Up @@ -274,13 +276,14 @@ static void tcpdev_read(void)

n = tcpcb_find_by_sock(sock);
if (!n || n->tcpcb.state == TS_CLOSED) {
printf("ktcp: panic in read\n");
debug_tcp("tcp: read on socket w/no CB\n");
retval_to_sock(sock, -EPIPE);
return;
}

cb = &n->tcpcb;
if (cb->state == TS_CLOSING || cb->state == TS_LAST_ACK || cb->state == TS_TIME_WAIT) {
printf("tcpdev_read: returning -EPIPE to socket read state %d\n", cb->state);
debug_tcp("tcp: read on socket w/invalid state %d\n", cb->state);
retval_to_sock(sock, -EPIPE);
return;
}
Expand All @@ -290,7 +293,7 @@ static void tcpdev_read(void)

if (data_avail == 0) {
if (cb->state == TS_CLOSE_WAIT) {
printf("tcpdev_read: read on CLOSE_WAIT socket, return -EPIPE\n");
debug_tcp("tcp: read on CLOSE_WAIT socket\n");
retval_to_sock(sock, -EPIPE);
} else if (db->nonblock)
retval_to_sock(sock, -EAGAIN);
Expand Down Expand Up @@ -385,17 +388,16 @@ static void tcpdev_write(void)

n = tcpcb_find_by_sock(sock);
if (!n || n->tcpcb.state == TS_CLOSED) {
printf("tcpdev_write: write to unknown socket\n");
debug_tcp("tcp: write on socket w/no CB\n");
retval_to_sock(sock, -EPIPE);
return;
}

cb = &n->tcpcb;

if (cb->state != TS_ESTABLISHED
/*&& cb->state != TS_CLOSE_WAIT*/) { // No write data if in CLOSE_WAIT
/* FIXME: May want to delete the printf below, this is not uncommon */
printf("tcpdev_write: write to socket in improper state %d\n", cb->state);
/* Don't write data if not established (or CLOSE_WAIT) */
if (cb->state != TS_ESTABLISHED /*&& cb->state != TS_CLOSE_WAIT*/ ) {
debug_tcp("tcp: write on socket w/invalid state %d\n", cb->state);
retval_to_sock(sock, -EPIPE);
return;
}
Expand Down
2 changes: 1 addition & 1 deletion elkscmd/rootfs_template/etc/net.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ netstart="telnetd ftpd"

# specific daemon command lines, named in netstart=
telnetd="telnetd"
ftpd="ftpd -d -N 10.0.2.2 -P 49152:49153"
ftpd="ftpd -d -P 49152:49159"
httpd="httpd"
audiorcv="audiorcv -d -r 8000"

Expand Down
11 changes: 8 additions & 3 deletions qemu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,13 @@ CONSOLE="-serial stdio"
# Incoming http forwarding: example: connect to ELKS httpd with 'http://localhost:8080'
# HOSTFWD="-net user,hostfwd=tcp:127.0.0.1:8080-10.0.2.15:80"

# Simultaneous telnet, http and ftp forwarding
# Port 4950 is the audiorcv default, so a host audio sender can reach it
# Simultaneous telnet/2323, ftp/2121, http/8080, and audiorcv/4950 forwarding
FWD="\
hostfwd=tcp:127.0.0.1:8080-10.0.2.15:80,\
hostfwd=tcp:127.0.0.1:2323-10.0.2.15:23,\
hostfwd=tcp::8020-:20,\
hostfwd=tcp::2121-:21,\
hostfwd=tcp::4950-:4950,\
hostfwd=tcp::8041-:49821,\
hostfwd=tcp::8042-:49822,\
hostfwd=tcp::8043-:49823,\
Expand All @@ -105,7 +105,12 @@ hostfwd=tcp::8048-:49828,\
hostfwd=tcp::8049-:49829,\
hostfwd=tcp::49152-:49152,\
hostfwd=tcp::49153-:49153,\
hostfwd=tcp::4950-:4950"
hostfwd=tcp::49154-:49154,\
hostfwd=tcp::49155-:49155,\
hostfwd=tcp::49156-:49156,\
hostfwd=tcp::49157-:49157,\
hostfwd=tcp::49158-:49158,\
hostfwd=tcp::49159-:49159"

# new style
#NET="-net nic,model=ne2k_isa -net user,$FWD"
Expand Down
Loading