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
7 changes: 4 additions & 3 deletions elks/include/linuxmt/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <linuxmt/socket.h>

/* Number of protocols */
#define NPROTO 3
#define NPROTO 2

#define SOCK_INODE(S) ((S)->inode)

Expand All @@ -27,14 +27,14 @@ struct socket {
struct inode *inode;
struct file *file;

#if defined(CONFIG_UNIX)
#ifdef CONFIG_UNIX
struct socket *conn;
struct socket *iconn;
struct socket *next;
void *data;
#endif

#if defined(CONFIG_INET)
#ifdef CONFIG_INET
sem_t sem; /* one operation at a time per socket */
int avail_data; /* data available for reading from ktcp */
int retval; /* event return value from ktcp */
Expand Down Expand Up @@ -72,6 +72,7 @@ struct proto_ops {
#define SF_RST_ON_CLOSE (1 << 4) /* inet */
#define SF_REUSE_ADDR (1 << 5) /* inet */
#define SF_CONNECT (1 << 6) /* inet */
#define SF_NOBUF (1 << 7) /* inet */

struct net_proto {
const char *name; /* Protocol name */
Expand Down
32 changes: 14 additions & 18 deletions elks/include/linuxmt/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,39 @@

#include <linuxmt/types.h>

#define MAX_SOCK_ADDR 110 /* Sufficient size for AF_UNIX */

struct sockaddr {
unsigned short sa_family;
char sa_data [MAX_SOCK_ADDR];
char sa_data[20]; /* sufficient size for AF_UNIX sockaddr_un in un.h */
};

/* for setsockopt(2) */
#define SOL_SOCKET 1
/* setsockopt parameters */
#define SOL_SOCKET 1

/* careful: option names are close to internal SF_ options in net.h*/
#define SO_REUSEADDR 2
#define SO_RCVBUF 8 /* set TCP CB receive buffer size*/
#define SO_LINGER 13 /* only implemented for l_linger = 0*/
#define SO_REUSEADDR 2
#define SO_RCVBUF 8 /* set TCP CB receive buffer size*/
#define SO_LINGER 13 /* only implemented for l_linger = 0*/

/* non-standard options */
#define SO_LISTEN_BUFSIZ 128 /* suggested buffer size for listen to save mem*/
#define SO_NOBUFFER 14 /* don't allocate rcv buffer (e.g. for listen) */

struct linger {
int l_onoff; /* Linger active */
int l_linger; /* How long to linger for */
};

#define AF_INET 0
#define AF_UNIX 1
#define AF_INET 0
#define AF_UNIX 1

#define PF_INET AF_INET
#define PF_UNIX AF_UNIX
#define PF_INET AF_INET
#define PF_UNIX AF_UNIX

#define AF_LOCAL AF_UNIX
#define PF_LOCAL PF_UNIX

#define SOCK_STREAM 1 /* stream (connection) socket */
#define SOCK_DGRAM 2 /* datagram (conn.less) socket */
#define SOCK_RAW 3 /* raw socket */
#define SOCK_RDM 4 /* reliably-delivered message */
#define SOCK_SEQPACKET 5 /* sequential packet socket */
#define SOCK_STREAM 1 /* stream (connection) socket */
#define SOCK_DGRAM 2 /* datagram (conn.less) socket */
#define SOCK_RAW 3 /* raw socket */

#ifdef __KERNEL__
struct proto_ops;
Expand Down
7 changes: 3 additions & 4 deletions elks/include/linuxmt/tcpdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
#include <linuxmt/in.h>
#include <linuxmt/net.h>

#define TCP_DEVICE_NAME "tcpdev"

/* should be equal to PTYOUTQ_SIZE and telnetd buffer size*/
#define TDB_WRITE_MAX 512 /* max data in tdb_write packet to ktcp*/

Expand All @@ -30,7 +28,7 @@
struct tdb_release {
unsigned char cmd;
struct socket *sock;
int reset;
int reset; /* SO_LINGER -> SF_RST_ON_CLOSE */
};

struct tdb_accept {
Expand All @@ -49,7 +47,8 @@ struct tdb_listen {
struct tdb_bind {
unsigned char cmd;
struct socket *sock;
int reuse_addr;
int reuse_addr; /* SO_REUSEADDR -> SF_REUSE_ADDR */
int no_buffer; /* SO_NOBUFFER -> SF_NOBUF */
int rcv_bufsiz;
struct sockaddr_in addr;
};
Expand Down
1 change: 1 addition & 0 deletions elks/net/ipv4/af_inet.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ static int inet_bind(register struct socket *sock, struct sockaddr *addr,
cmd->cmd = TDC_BIND;
cmd->sock = sock;
cmd->reuse_addr = sock->flags & SF_REUSE_ADDR;
cmd->no_buffer = sock->flags & SF_NOBUF;
cmd->rcv_bufsiz = sock->rcv_bufsiz;
memcpy_fromfs(&cmd->addr, addr, sockaddr_len);

Expand Down
8 changes: 5 additions & 3 deletions elks/net/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,6 @@ static struct proto_ops *find_protocol_family(int family)

static int check_addr_to_kernel(void *uaddr, size_t ulen)
{
if (ulen > MAX_SOCK_ADDR)
return -EINVAL;

if (ulen == 0)
return 0;

Expand Down Expand Up @@ -577,6 +574,11 @@ int sys_setsockopt(int fd, int level, int option_name, void *option_value,
flags = SF_REUSE_ADDR;
break;

case SO_NOBUFFER:
setoption = 1;
flags = SF_NOBUF;
break;

default:
return -EINVAL;
}
Expand Down
5 changes: 2 additions & 3 deletions elkscmd/audio/audiorcv.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,8 @@ int main(int argc, char **argv)
perror("SO_REUSEADDR");

/* set small listen buffer to save ktcp memory */
val = SO_LISTEN_BUFSIZ;
if (setsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, &val, sizeof(int)) < 0)
perror("SO_RCVBUF");
if (setsockopt(listen_sock, SOL_SOCKET, SO_NOBUFFER, NULL, 0) < 0)
perror("SO_NOBUFFER");

memset(&localadr, 0, sizeof(localadr));
localadr.sin_family = AF_INET;
Expand Down
5 changes: 2 additions & 3 deletions elkscmd/inet/ftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -820,9 +820,8 @@ int do_active(int cmdfd) {
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
perror("SO_REUSEADDR");

i = SO_LISTEN_BUFSIZ;
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &i, sizeof(i)) < 0)
perror("SO_RCVBUF");
if (setsockopt(fd, SOL_SOCKET, SO_NOBUFFER, NULL, 0) < 0)
perror("SO_NOBUFFER");

bzero(&myaddr, sizeof(myaddr));
myaddr.sin_family = AF_INET;
Expand Down
17 changes: 10 additions & 7 deletions elkscmd/inet/ftpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,12 +494,16 @@ int do_pasv(int *datafd, int epsv) {
perror("PASV socket");
return -1;
}

if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) < 0)
perror("PASV SO_REUSEADDR");
i = SO_LISTEN_BUFSIZ;
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &i, sizeof(i)) < 0)
perror("PASV SO_RCVBUF");
if (setsockopt(fd, SOL_SOCKET, SO_NOBUFFER, NULL, 0) < 0)
perror("PASV SO_NOBUFFER");
#if 1
/* test using 2/3 of normal 4390 byte buffer (=MTU-40 = 1460*2) */
int size = 2920;
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) < 0)
perror("SO_RCVBUF");
#endif

pasv.sin_family = AF_INET;
pasv.sin_addr.s_addr = htonl(INADDR_ANY);
Expand Down Expand Up @@ -700,9 +704,8 @@ int main(int argc, char **argv) {
perror("SO_REUSEADDR");

/* set small listen buffer to save ktcp memory */
ret = SO_LISTEN_BUFSIZ;
if (setsockopt(listenfd, SOL_SOCKET, SO_RCVBUF, &ret, sizeof(int)) < 0)
perror("SO_RCVBUF");
if (setsockopt(listenfd, SOL_SOCKET, SO_NOBUFFER, NULL, 0) < 0)
perror("SO_NOBUFFER");

servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
Expand Down
5 changes: 2 additions & 3 deletions elkscmd/inet/httpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,8 @@ int main(int argc, char **argv)
errmsg("http: SO_REUSEADDR");

/* set small listen buffer to save ktcp memory */
ret = SO_LISTEN_BUFSIZ;
if (setsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, &ret, sizeof(int)) < 0)
errmsg("httpd: SO_RCVBUF");
if (setsockopt(listen_sock, SOL_SOCKET, SO_NOBUFFER, NULL, 0) < 0)
errmsg("httpd: SO_NOBUFFER");

localadr.sin_family = AF_INET;
localadr.sin_port = htons(DEF_PORT);
Expand Down
5 changes: 2 additions & 3 deletions elkscmd/inet/telnetd.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,8 @@ main(int argc, char **argv)
perror("SO_REUSEADDR");

/* set small listen buffer to save ktcp memory */
ret = SO_LISTEN_BUFSIZ;
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &ret, sizeof(int)) < 0)
perror("SO_RCVBUF");
if (setsockopt(sockfd, SOL_SOCKET, SO_NOBUFFER, NULL, 0) < 0)
perror("SO_NOBUFFER");

memset(&addr_in, 0, sizeof(addr_in));
addr_in.sin_family = AF_INET;
Expand Down
4 changes: 2 additions & 2 deletions elkscmd/ktcp/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,8 @@ static void tcp_listen(struct iptcp_s *iptcp, struct tcpcb_s *lcb)
if (h->flags & TF_ACK)
debug_tcp("tcp: ACK in listen not implemented\n");

/* duplicate control block but with normal sized input buffer, SO_RCVBUF ignored for now */
n = tcpcb_clone(lcb, CB_NORMAL_BUFSIZ); /* copy lcb into linked list*/
/* duplicate CB with normal or SO_RCVBUF sized buffer */
n = tcpcb_clone(lcb, lcb->acc_size? lcb->acc_size: CB_NORMAL_BUFSIZ);
if (!n)
return; /* no memory for new connection*/
cb = &n->tcpcb;
Expand Down
1 change: 1 addition & 0 deletions elkscmd/ktcp/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ struct tcpcb_s {
__u16 buf_tail;
__u16 buf_used; /* # valid bytes in buffer */
__u16 buf_size; /* total buffer size */
__u16 acc_size; /* accept CB buffer size from SO_RCVBUF */
__u8 buf_base[];
};

Expand Down
6 changes: 5 additions & 1 deletion elkscmd/ktcp/tcp_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,10 +474,14 @@ void tcp_output(struct tcpcb_s *cb)
header_len = sizeof(tcphdr_t);
if (cb->flags & TF_SYN) {
__u8 *options = th->options;
unsigned int mss = MTU - 40;

/* advertise segment we can actually accept */
if (cb->buf_size && mss > cb->buf_size)
mss = cb->buf_size;
options[0] = TCP_OPT_MSS;
options[1] = TCP_OPT_MSS_LEN; /* total options length (4)*/
*(__u16 *)(options + 2) = htons(MTU - 40);
*(__u16 *)(options + 2) = htons(mss);
header_len += TCP_OPT_MSS_LEN;
}

Expand Down
11 changes: 8 additions & 3 deletions elkscmd/ktcp/tcpdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ static void tcpdev_bind(void)
{
struct tdb_bind *db = (struct tdb_bind *)sbuf; /* read from sbuf*/
struct tcpcb_list_s *n;
int size;
int size = 0;
__u16 port;
struct tdb_bind_ret bind_ret;

Expand All @@ -76,8 +76,12 @@ static void tcpdev_bind(void)
return;
}

/* SO_RCVBUF currently only sets listen or connect buffer size, NOT accept size!*/
size = db->rcv_bufsiz? db->rcv_bufsiz: CB_NORMAL_BUFSIZ;
/*
* Use SO_NOBUFFER on listen sockets to save ktcp heap.
* Use SO_RCVBUF set connect or accept CB buffer size.
*/
if (!db->no_buffer)
size = db->rcv_bufsiz? db->rcv_bufsiz: CB_NORMAL_BUFSIZ;
n = tcpcb_new(size);
if (n == NULL) {
retval_to_sock(db->sock,-ENOMEM);
Expand Down Expand Up @@ -117,6 +121,7 @@ static void tcpdev_bind(void)
}

n->tcpcb.sock = db->sock;
n->tcpcb.acc_size = db->rcv_bufsiz;
if (db->addr.sin_addr.s_addr == htonl(0x7f000001))
n->tcpcb.localaddr = db->addr.sin_addr.s_addr;
else
Expand Down
Loading