Basic socket stubs and functionalities.
authorDavid Zhu <yuzhu@cs.berkeley.edu>
Fri, 14 Sep 2012 00:03:19 +0000 (17:03 -0700)
committerDavid Zhu <yuzhu@cs.berkeley.edu>
Wed, 20 Mar 2013 20:07:25 +0000 (13:07 -0700)
Putting the socket interface in place, and some initial implementation of sockets
for tcp.

16 files changed:
kern/arch/i686/x86.h
kern/include/alarm.h
kern/include/assert.h
kern/include/endian.h
kern/include/net.h
kern/include/net/tcp.h
kern/include/net/timers.h [new file with mode: 0644]
kern/include/ros/bits/syscall.h
kern/include/ros/errno.h
kern/include/socket.h
kern/src/Makefrag
kern/src/net/tcp.c
kern/src/socket.c
kern/src/syscall.c
tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/accept.c [new file with mode: 0644]
tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/listen.c [new file with mode: 0644]

index 84f0c57..dc610aa 100644 (file)
@@ -338,4 +338,8 @@ __cpu_relax(void)
        asm volatile("pause" : : : "memory");
 }
 
+#ifndef UNUSED_ARG
+#define UNUSED_ARG(x) (void)x
+#endif /* This prevents compiler warnings for UNUSED_ARG */ 
+
 #endif /* !ROS_INC_X86_H */
index 4386f34..625182f 100644 (file)
@@ -44,6 +44,8 @@
 #include <ros/common.h>
 #include <sys/queue.h>
 #include <kthread.h>
+#include <alarm.h>
+
 
 /* These structures allow code to block or defer work for a certain amount of
  * time.  Timer chains (like off a per-core timer) are made of lists/trees of
@@ -62,6 +64,8 @@ struct alarm_waiter {
 };
 TAILQ_HEAD(awaiters_tailq, alarm_waiter);              /* ideally not a LL */
 
+typedef void (* alarm_handler)(struct alarm_waiter *waiter);
+
 /* One of these per alarm source, such as a per-core timer.  Based on the
  * source, you may need a lock (such as for a global timer).  set_interrupt() is
  * a method for setting the interrupt source. */
index de94831..b765dbe 100644 (file)
@@ -10,6 +10,9 @@ void ( _panic)(const char* NTS, int, const char* NTS, ...)
 #define warn(...) _warn(__FILE__, __LINE__, __VA_ARGS__)
 #define panic(...) _panic(__FILE__, __LINE__, __VA_ARGS__)
 
+#define check(x)               \
+       do { if (!(x)) warn("warning failed: %s", #x); } while (0)
+
 #define assert(x)              \
        do { if (!(x)) panic("assertion failed: %s", #x); } while (0)
 
index be7ddfb..42c6027 100644 (file)
 #define be32_to_cpu(x) byte_swap32((x))
 #define be64_to_cpu(x) byte_swap64((x))
 
+#define PP_HTONS(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
+#define PP_NTOHS(x) PP_HTONS(x)
+#define PP_HTONL(x) ((((x) & 0xff) << 24) | \
+                     (((x) & 0xff00) << 8) | \
+                     (((x) & 0xff0000UL) >> 8) | \
+                     (((x) & 0xff000000UL) >> 24))
+#define PP_NTOHL(x) PP_HTONL(x)
+
 #else /* big endian */
 
 # ifndef BIG_ENDIAN
 #define be32_to_cpu(x) ((uint32_t)(x))
 #define be64_to_cpu(x) ((uint64_t)(x))
 
+#define PP_HTONS(x) (x)
+#define PP_NTOHS(x) (x)
+#define PP_HTONL(x) (x)
+#define PP_NTOHL(x) (x)
+
 #endif /* endian */
 
 #endif /* ROS_KERN_ENDIAN_H */
index f521fc9..8524065 100644 (file)
@@ -12,8 +12,6 @@
 #include <net/pbuf.h>
 #include <stdio.h>
 
-/* network internal error code */
-#define ERR_BUF 
 
 /* A few other useful standard defines.  Note the IP header can change size. */
 #define ETH_HDR_SZ 14 // without padding, 16 with padding
@@ -30,7 +28,7 @@
 #define DEFAULT_TTL 64
 #define DEFAULT_MTU 1500
 // is this network order already?
-#define IP_ADDR 0x0A000002  //lookout for address order
+#define LOCAL_IP_ADDR (struct in_addr) {0x0A000002}  //lookout for address order
 
 
 /* Don't forget the bytes are in network order */
@@ -47,6 +45,8 @@ struct ethernet_hdr {
 #define IP_MF 0x2000        /* more fragments flag */
 #define IP_OFFMASK 0x1fff   /* mask for fragmenting bits */
 
+#define PACK_STRUCT_FIELD(x) x __attribute__((packed))
+
 /* For the bit-enumerated fields, note that you need to read "backwards" through
  * the byte (first bits in memory are the "LSB" of the byte).  Can't seem to be
  * able to do it with flags/fragments (3/13 bits each...). */
@@ -74,7 +74,19 @@ struct udp_hdr {
        uint16_t                                        dst_port;
        uint16_t                                        length;
        uint16_t                                        checksum;
-};
+} __attribute__((packed));
+
+struct tcp_hdr {
+  PACK_STRUCT_FIELD(uint16_t src);
+  PACK_STRUCT_FIELD(uint16_t dest);
+  PACK_STRUCT_FIELD(uint32_t seqno);
+  PACK_STRUCT_FIELD(uint32_t ackno);
+  PACK_STRUCT_FIELD(uint16_t _hdrlen_rsvd_flags);
+  PACK_STRUCT_FIELD(uint16_t wnd);
+  PACK_STRUCT_FIELD(uint16_t chksum);
+  PACK_STRUCT_FIELD(uint16_t urgp);
+} __attribute__((packed));
+
 /* src and dst are in network order*/
 uint16_t inet_chksum_pseudo(struct pbuf *p, uint32_t src, uint32_t dest, uint8_t proto, uint16_t proto_len);
 uint16_t __ip_checksum(void *buf, unsigned int len, uint32_t sum);
index 792c6ea..2a5ddbf 100644 (file)
@@ -45,7 +45,7 @@ extern "C" {
  * an upper limit on the MSS advertised by the remote host.
  */
 #ifndef TCP_MSS
-#define TCP_MSS                         (536)
+#define TCP_MSS                         (512)
 #endif
 
 /**
diff --git a/kern/include/net/timers.h b/kern/include/net/timers.h
new file mode 100644 (file)
index 0000000..c7aaa71
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *         Simon Goldschmidt
+ * Modified to fit Akaros by David Zhu<yuzhu@cs.berkeley.edu>
+ *
+ */
+#ifndef __NET_TIMERS_H__
+#define __NET_TIMERS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef LWIP_DEBUG_TIMERNAMES
+#define LWIP_DEBUG_TIMERNAMES 1
+#else
+#define LWIP_DEBUG_TIMERNAMES 0
+#endif
+
+#include <alarm.h>
+
+/** Function prototype for a timeout callback function. Register such a function
+ * using sys_timeout().
+ *
+ * @param arg Additional argument to pass to the function - set up by sys_timeout()
+ */
+typedef void (* sys_timeout_handler)(struct alarm_waiter *arg);
+struct timer_req {
+       sys_timeout_handler func;
+       void *arg;
+};
+#if 0
+struct sys_timeo {
+  struct sys_timeo *next;
+  uint32_t time;
+  sys_timeout_handler h;
+  void *arg;
+#if LWIP_DEBUG_TIMERNAMES
+  const char* handler_name;
+#endif /* LWIP_DEBUG_TIMERNAMES */
+};
+#endif
+void sys_timeouts_init(void);
+
+struct alarm_waiter* sys_timeout(uint32_t msecs, sys_timeout_handler handler, struct alarm_waiter* waiter);
+
+void sys_untimeout(sys_timeout_handler handler, void *arg);
+void sys_check_timeouts(void);
+void sys_restart_timeouts(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __NET_TIMERS_H__  */
index 38bad17..b75f7b1 100644 (file)
 #define SYS_sendto                                     41
 #define SYS_recvfrom                           42
 #define SYS_select          43
-
+#define SYS_connect                              44
+#define SYS_send                                               45
+#define SYS_recv                                               46
+#define SYS_bind                                               47
+#define SYS_accept                                     48
 
 /* Platform specific syscalls */
 #define SYS_serial_read                                75
index fe497aa..27a9665 100644 (file)
 #define EUNSPECIFIED   136 /* Unspecified */
 #define EMORON                 137 /* Moron */
 
+
 #endif
index 8561311..1b8fefb 100644 (file)
@@ -6,6 +6,7 @@
 #include <atomic.h>
 #include <net/pbuf.h>
 #include <kthread.h>
+#include <net/ip.h>
 #include <vfs.h>
 // Just a couple of AF types that we might support
 #define AF_UNSPEC      0
@@ -69,9 +70,6 @@ struct socket{
        //struct  protosw *so_proto;  /* (a) protocol handle */
 };
 
-struct in_addr {
-    uint32_t s_addr;
-};
 
 /* members are in network byte order */
 struct sockaddr_in {
@@ -104,10 +102,61 @@ struct msghdr {
 };
 
 
+/* Socket-level options for `getsockopt' and `setsockopt'.  */
+enum
+  {
+    SO_DEBUG = 0x0001,         /* Record debugging information.  */
+#define SO_DEBUG SO_DEBUG
+    SO_ACCEPTCONN = 0x0002,    /* Accept connections on socket.  */
+#define SO_ACCEPTCONN SO_ACCEPTCONN
+    SO_REUSEADDR = 0x0004,     /* Allow reuse of local addresses.  */
+#define SO_REUSEADDR SO_REUSEADDR
+    SO_KEEPALIVE = 0x0008,     /* Keep connections alive and send
+                                  SIGPIPE when they die.  */
+#define SO_KEEPALIVE SO_KEEPALIVE
+    SO_DONTROUTE = 0x0010,     /* Don't do local routing.  */
+#define SO_DONTROUTE SO_DONTROUTE
+    SO_BROADCAST = 0x0020,     /* Allow transmission of
+                                  broadcast messages.  */
+#define SO_BROADCAST SO_BROADCAST
+    SO_USELOOPBACK = 0x0040,   /* Use the software loopback to avoid
+                                  hardware use when possible.  */
+#define SO_USELOOPBACK SO_USELOOPBACK
+    SO_LINGER = 0x0080,                /* Block on close of a reliable
+                                  socket to transmit pending data.  */
+#define SO_LINGER SO_LINGER
+    SO_OOBINLINE = 0x0100,     /* Receive out-of-band data in-band.  */
+#define SO_OOBINLINE SO_OOBINLINE
+    SO_REUSEPORT = 0x0200,     /* Allow local address and port reuse.  */
+#define SO_REUSEPORT SO_REUSEPORT
+    SO_SNDBUF = 0x1001,                /* Send buffer size.  */
+#define SO_SNDBUF SO_SNDBUF
+    SO_RCVBUF = 0x1002,                /* Receive buffer.  */
+#define SO_RCVBUF SO_RCVBUF
+    SO_SNDLOWAT = 0x1003,      /* Send low-water mark.  */
+#define SO_SNDLOWAT SO_SNDLOWAT
+    SO_RCVLOWAT = 0x1004,      /* Receive low-water mark.  */
+#define SO_RCVLOWAT SO_RCVLOWAT
+    SO_SNDTIMEO = 0x1005,      /* Send timeout.  */
+#define SO_SNDTIMEO SO_SNDTIMEO
+    SO_RCVTIMEO = 0x1006,      /* Receive timeout.  */
+#define SO_RCVTIMEO SO_RCVTIMEO
+    SO_ERROR = 0x1007,         /* Get and clear error status.  */
+#define SO_ERROR SO_ERROR
+    SO_STYLE = 0x1008,         /* Get socket connection style.  */
+#define SO_STYLE SO_STYLE
+    SO_TYPE = SO_STYLE         /* Compatible name for SO_STYLE.  */
+#define SO_TYPE SO_TYPE
+  };
+#define SO_INHERITED   (SO_REUSEADDR|SO_KEEPALIVE|SO_LINGER)
 
 extern struct kmem_cache *sock_kcache;
 extern struct kmem_cache *mbuf_kcache;
 extern struct kmem_cache *udp_pcb_kcache;
+extern struct kmem_cache *tcp_pcb_kcache;
+extern struct kmem_cache *tcp_pcb_listen_kcache;
+extern struct kmem_cache *tcp_segment_kcache;
+
 
 void socket_init();
 intreg_t send_iov(struct socket* sock, struct iovec* iov, int flags);
@@ -118,6 +167,12 @@ intreg_t sys_sendto(struct proc *p, int socket, const void *buffer, size_t lengt
 intreg_t sys_recvfrom(struct proc *p, int socket, void *restrict buffer, size_t length, int flags, struct sockaddr *restrict address, socklen_t *restrict address_len);
 intreg_t sys_select(struct proc *p, int nfds, fd_set *readfds, fd_set *writefds,
                                fd_set *exceptfds, struct timeval *timeout);
+intreg_t sys_connect(struct proc *p, int sockfd, const struct sockaddr *addr, socklen_t addrlen);
+intreg_t sys_send(struct proc *p, int sockfd, const void *buf, size_t len, int flags);
+intreg_t sys_recv(struct proc *p, int sockfd, void *buf, size_t len, int flags);
+intreg_t sys_bind(struct proc* p, int sockfd, const struct sockaddr *addr, socklen_t addrlen);
+intreg_t sys_accept(struct proc *p, int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+intreg_t sys_listen(struct proc *p, int sockfd, int backlog);
 
 
 #endif /* ROS_SOCKET_H */
index 12829b3..93b10c6 100644 (file)
@@ -62,8 +62,12 @@ KERN_SRCFILES := $(KERN_ARCH_SRCFILES) \
                  $(KERN_SRC_DIR)/socket.c \
                  $(KERN_SRC_DIR)/arsc.c \
                  $(KERN_SRC_DIR)/net/udp.c \
+                 $(KERN_SRC_DIR)/net/tcp.c \
                  $(KERN_SRC_DIR)/net/ip.c \
-                 $(KERN_SRC_DIR)/net/pbuf.c
+                 $(KERN_SRC_DIR)/net/pbuf.c \
+                 $(KERN_SRC_DIR)/net/tcp_out.c \
+                 $(KERN_SRC_DIR)/net/tcp_in.c \
+                 $(KERN_SRC_DIR)/net/timers.c
 
 
 # Only build files if they exist.
index 455a19b..6035661 100644 (file)
@@ -938,7 +938,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, uint16_t port,
   /* As initial send MSS, we use TCP_MSS but limit it to 536.
      The send MSS is updated when an MSS option is received. */
   pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
-#if TCP_CALCULATE_EFF_SEND_MSS
+#if TCP_CALCULATE_EFF_SEND_MSS 
   pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr);
 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
   pcb->cwnd = 1;
@@ -946,7 +946,6 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, uint16_t port,
 #if LWIP_CALLBACK_API
   pcb->connected = connected;
 #else /* LWIP_CALLBACK_API */  
-  LWIP_UNUSED_ARG(connected);
 #endif /* LWIP_CALLBACK_API */
 
   /* Send a SYN together with the MSS option. */
index f83a4de..83ba381 100644 (file)
 #include <ros/errno.h>
 #include <net.h>
 #include <net/udp.h>
+#include <net/tcp.h>
 #include <net/pbuf.h>
+#include <net/tcp_impl.h>
 #include <umem.h>
 #include <kthread.h>
 #include <bitmask.h>
+#include <debug.h>
 /*
  *TODO: Figure out which socket.h is used where
  *There are several socket.h in kern, and a couple more in glibc. Perhaps the glibc ones
 struct kmem_cache *sock_kcache;
 struct kmem_cache *mbuf_kcache;
 struct kmem_cache *udp_pcb_kcache;
+struct kmem_cache *tcp_pcb_kcache;
+struct kmem_cache *tcp_pcb_listen_kcache;
+struct kmem_cache *tcp_segment_kcache;
+
 // file ops needed to support read/write on socket fd
 static struct file_operations socket_op = {
        0,
@@ -77,11 +84,6 @@ struct socket* alloc_sock(int socket_family, int socket_type, int protocol){
        init_sem(&newsock->sem, 0);
        spinlock_init(&newsock->waiter_lock);
        LIST_INIT(&newsock->waiters);
-       if (socket_type == SOCK_DGRAM){
-               newsock->so_pcb = udp_new();
-               /* back link */
-               ((struct udp_pcb*) (newsock->so_pcb))->pcbsock = newsock;
-       }
        return newsock;
 
 }
@@ -113,18 +115,137 @@ void socket_init(){
        /* allocate buf for socket */
        sock_kcache = kmem_cache_create("socket", sizeof(struct socket),
                                                                        __alignof__(struct socket), 0, 0, 0);
-       udp_pcb_kcache = kmem_cache_create("udppcb", sizeof(struct udp_pcb), 
+       udp_pcb_kcache = kmem_cache_create("udppcb", sizeof(struct udp_pcb),
                                                                        __alignof__(struct udp_pcb), 0, 0, 0);
-
+       tcp_pcb_kcache = kmem_cache_create("tcppcb", sizeof(struct tcp_pcb),
+                                                                       __alignof__(struct tcp_pcb), 0, 0, 0);
+       tcp_pcb_listen_kcache = kmem_cache_create("tcppcblisten", sizeof(struct tcp_pcb_listen),
+                                                                       __alignof__(struct tcp_pcb_listen), 0, 0, 0);
+       tcp_segment_kcache = kmem_cache_create("tcpsegment", sizeof(struct tcp_seg),
+                                                                       __alignof__(struct tcp_seg), 0, 0, 0);
        pbuf_init();
 
 }
+intreg_t sys_accept(struct proc *p, int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
+       printk ("sysaccept called\n");
+       struct socket* sock = getsocket(p, sockfd);
+       struct sockaddr_in *in_addr = (struct sockaddr_in *)addr;
+       uint16_t r_port;
+       if (sock == NULL) {
+               set_errno(EBADF);
+               return -1;      
+       }
+       if (sock->so_type == SOCK_DGRAM){
+               return -1; // indicates false for connect
+       } else if (sock->so_type == SOCK_STREAM) {
+               // check if the socket is in WAIT state
+               // pulling new socket from the queue
+       }
+       return -1;
+}
+static error_t accept_callback(void *arg, struct tcp_pcb *newpcb, error_t err) {
+       struct socket *sockold = (struct socket *) arg;
+       struct socket *sock = alloc_sock(sockold->so_family, sockold->so_type, sockold->so_protocol);
+       struct file *file = alloc_socket_file(sock);
+       
+       sock->so_pcb = newpcb;
+       newpcb->pcbsock = sock;
+       if (file == NULL) return -1;
+       kref_put(&file->f_kref);
+       return 0;
+}
+intreg_t sys_listen(struct proc *p, int sockfd, int backlog) {
+       struct socket* sock = getsocket(p, sockfd);
+       if (sock == NULL) {
+               set_errno(EBADF);
+               return -1;      
+       }
+       if (sock->so_type == SOCK_DGRAM){
+               return -1; // indicates false for connect
+       } else if (sock->so_type == SOCK_STREAM) {
+               // check if the socket is in WAIT state
+               struct tcp_pcb *tpcb = (struct tcp_pcb*)sock->so_pcb;
+               struct tcp_pcb* lpcb = tcp_listen_with_backlog(tpcb, backlog);
+               if (lpcb == NULL) {
+                       return -1;
+               }
+               sock->so_pcb = lpcb;
+
+               // register callback for new connection
+               tcp_arg(lpcb, sock);                                                  
+               tcp_accept(lpcb, accept_callback); 
+
+               return 0;
+
+
+               // XXX: add backlog later
+       }
+       return -1;
+}
+intreg_t sys_connect(struct proc *p, int sock_fd, const struct sockaddr* addr, int addrlen) {
+       printk("sys_connect called \n");
+       struct socket* sock = getsocket(p, sock_fd);
+       struct sockaddr_in *in_addr = (struct sockaddr_in *)addr;
+       uint16_t r_port;
+       if (sock == NULL) {
+               set_errno(EBADF);
+               return -1;      
+       }
+       if (sock->so_type == SOCK_DGRAM){
+               return -1; // indicates false for connect
+       } else if (sock->so_type == SOCK_STREAM) {
+               error_t err = tcp_connect((struct tcp_pcb*)sock->so_pcb, & (in_addr->sin_addr), in_addr->sin_port, NULL);
+               return err;
+       }
+
+       return -1;
+}
+
+intreg_t sys_send(struct proc *p, int sockfd, const void *buf, size_t len, int flags) {
+       printk("sys_send called \n");
+       return len; // indicates success, by returning length
+
+}
+intreg_t sys_recv(struct proc *p, int sockfd, void *buf, size_t len, int flags) {
+       printk("sys_recv called \n");
+       // return actual length filled
+       return len;
+}
 
+intreg_t sys_bind(struct proc* p_proc, int fd, const struct sockaddr *addr, socklen_t addrlen) {
+       struct socket* sock = getsocket(p_proc, fd);
+       const struct sockaddr_in *in_addr = (const struct sockaddr_in *)addr;
+       uint16_t r_port;
+       if (sock == NULL) {
+               set_errno(EBADF);
+               return -1;      
+       }
+       if (sock->so_type == SOCK_DGRAM){
+               return udp_bind((struct udp_pcb*)sock->so_pcb, & (in_addr->sin_addr), in_addr->sin_port);
+       } else if (sock->so_type == SOCK_STREAM) {
+               return tcp_bind((struct tcp_pcb*)sock->so_pcb, & (in_addr->sin_addr), in_addr->sin_port);
+       } else {
+               printk("SOCK type not supported in bind operation \n");
+               return -1;
+       }
+       return 0;
+}
 intreg_t sys_socket(struct proc *p, int socket_family, int socket_type, int protocol){
        //check validity of params
-       if (socket_family !=AF_INET && socket_type!=SOCK_DGRAM)
+       if (socket_family != AF_INET && socket_type != SOCK_DGRAM)
                return 0;
        struct socket *sock = alloc_sock(socket_family, socket_type, protocol);
+       if (socket_type == SOCK_DGRAM){
+               /* udp socket */
+               sock->so_pcb = udp_new();
+               /* back link */
+               ((struct udp_pcb*) (sock->so_pcb))->pcbsock = sock;
+       } else if (socket_type == SOCK_STREAM) {
+               /* tcp socket */
+               sock->so_pcb = tcp_new();
+               ((struct tcp_pcb*) (sock->so_pcb))->pcbsock = sock;
+       }
        struct file *file = alloc_socket_file(sock);
        
        if (file == NULL) return -1;
@@ -137,6 +258,7 @@ intreg_t sys_socket(struct proc *p, int socket_family, int socket_type, int prot
        printk("Socket open, res = %d\n", fd);
        return fd;
 }
+
 intreg_t send_iov(struct socket* sock, struct iovec* iov, int flags){
        // COPY_COUNT: for each iov, copy into mbuf, and send
        // should not copy here, copy in the protocol..
@@ -146,6 +268,7 @@ intreg_t send_iov(struct socket* sock, struct iovec* iov, int flags){
        // finally time to check for validity of UA, in the protocol send
        return 0;       
 }
+
 /*TODO: iov support currently broken */
 int send_datagram(struct socket* sock, struct iovec* iov, int flags){
        // is this a connection oriented protocol? 
@@ -201,7 +324,7 @@ intreg_t sys_sendto(struct proc *p_proc, int fd, const void *buffer, size_t leng
        }
 
        return -1;
-  //TODO: support for sendmsg and iovectors? Let's get the basis working first!
+  //TODO: support for sendmsg and iovectors? Let's get the basics working first!
        #if 0 
        // use iovector to handle sendmsg calls too, and potentially scatter-gather
        struct msghdr msg;
index 28ff88c..c10c9e5 100644 (file)
@@ -1383,10 +1383,17 @@ const static struct sys_table_entry syscall_table[] = {
 #endif
        [SYS_change_to_m] = {(syscall_t)sys_change_to_m, "change_to_m"},
        [SYS_poke_ksched] = {(syscall_t)sys_poke_ksched, "poke_ksched"},
+
+// socket related syscalls
        [SYS_socket] ={(syscall_t)sys_socket, "socket"},
        [SYS_sendto] ={(syscall_t)sys_sendto, "sendto"},
        [SYS_recvfrom] ={(syscall_t)sys_recvfrom, "recvfrom"},
        [SYS_select] ={(syscall_t)sys_select, "select"},
+       [SYS_connect] = {(syscall_t)sys_connect, "connect"},
+       [SYS_send] ={(syscall_t)sys_send, "send"},
+       [SYS_recv] ={(syscall_t)sys_recv, "recvfrom"},
+       [SYS_bind] ={(syscall_t)sys_bind, "bind"},
+       [SYS_accept] ={(syscall_t)sys_accept, "accept"},
 
 
        [SYS_read] = {(syscall_t)sys_read, "read"},
diff --git a/tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/accept.c b/tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/accept.c
new file mode 100644 (file)
index 0000000..213dd16
--- /dev/null
@@ -0,0 +1,12 @@
+#include <sysdep.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <sys/socket.h>
+#include <ros/syscall.h>
+
+int __accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
+       return ros_syscall(SYS_accept, sockfd, addr, addrlen);
+}
+
+libc_hidden_def (__accept)
diff --git a/tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/listen.c b/tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/listen.c
new file mode 100644 (file)
index 0000000..2203eaf
--- /dev/null
@@ -0,0 +1,11 @@
+#include <sysdep.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <sys/socket.h>
+#include <ros/syscall.h>
+
+int __listen(int sockfd, int backlog) {
+       return ros_syscall(SYS_listen, sockfd, backlog);
+}
+weak_alias (__listen, listen)