Plan9 style waserror() handling
[akaros.git] / kern / include / socket.h
1 #ifndef ROS_SOCKET_H
2 #define ROS_SOCKET_H
3
4 #include <ros/common.h>
5 #include <sys/queue.h>
6 #include <atomic.h>
7 #include <net/pbuf.h>
8 #include <kthread.h>
9 #include <net/ip.h>
10 #include <vfs.h>
11 // Just a couple of AF types that we might support
12 #define AF_UNSPEC       0
13 #define AF_UNIX         1       /* Unix domain sockets          */
14 #define AF_LOCAL        1       /* POSIX name for AF_UNIX       */
15 #define AF_INET         2       /* Internet IP Protocol         */
16
17 #define PF_UNSPEC       AF_UNSPEC
18 #define PF_UNIX         AF_UNIX
19 #define PF_LOCAL        AF_LOCAL
20 #define PF_INET         AF_INET
21
22 #define SS_NOFDREF              0x0001  /* no file table ref any more */
23 #define SS_ISCONNECTED          0x0002  /* socket connected to a peer */
24 #define SS_ISCONNECTING         0x0004  /* in process of connecting to peer */
25 #define SS_ISDISCONNECTING      0x0008  /* in process of disconnecting */
26 #define SS_NBIO                 0x0100  /* non-blocking ops */
27 #define SS_ASYNC                0x0200  /* async i/o notify */
28 #define SS_ISCONFIRMING         0x0400  /* deciding to accept connection req */
29 #define SS_ISDISCONNECTED       0x2000  /* socket disconnected from peer */
30
31 /* Define an range for automatic port assignment */
32 #define SOCKET_PORT_START 4096
33 #define SOCKET_PORT_END  0x7fff
34
35 struct socket;
36 struct proc;
37 STAILQ_HEAD(socket_tailq, socket);
38 struct semaphore_entry;
39 LIST_HEAD(sock_semaphore_list, semaphore_entry);
40
41 // These are probably defined elsewhere too..
42 #ifndef socklen_t
43 typedef int socklen_t;
44 typedef int sa_family_t;
45 #endif
46 #define inet_addr_to_ipaddr_p(target_ipaddr_p, source_inaddr)   ((target_ipaddr_p) = (ip_addr_t*)&((source_inaddr)->s_addr))
47 enum sock_type {
48     SOCK_STREAM = 1,
49     SOCK_DGRAM  = 2,
50     SOCK_RAW    = 3,
51     SOCK_RDM    = 4,
52     SOCK_SEQPACKET  = 5,
53     SOCK_DCCP   = 6,
54     SOCK_PACKET = 10,
55 };
56
57 /* TODO: consider building this into struct semaphore */
58 struct semaphore_entry {
59         struct semaphore sem;
60         int fd;
61         LIST_ENTRY(semaphore_entry) link;
62 };
63
64 struct socket{
65   //int so_count;       /* (b) reference count */
66   short   so_type;        /* (a) generic type, see socket.h */
67         short   so_family;
68         int     so_protocol;
69   short   so_options;     /* from socket call, see socket.h */
70   //short   so_linger;      /* time to linger while closing */
71   short   so_state;       /* (b) internal state flags SS_* */
72         //int so_qstate;      /* (e) internal state flags SQ_* */
73         void    *so_pcb;        /* protocol control block */
74         struct pbuf_head recv_buff;
75         struct pbuf_head send_buff;
76         struct semaphore sem;
77         struct semaphore accept_sem;
78         spinlock_t waiter_lock;
79         struct sock_semaphore_list waiters; /* sem for a process to sleep on */
80         struct socket_tailq acceptq;
81         STAILQ_ENTRY(socket) next;
82         //struct  vnet *so_vnet;      /* network stack instance */
83         //struct  protosw *so_proto;  /* (a) protocol handle */
84 };
85
86
87 /* members are in network byte order */
88 struct sockaddr_in {
89     // uint8_t sin_len; -- bsd only field
90     uint8_t sin_family;
91     uint16_t sin_port;
92     struct in_addr sin_addr;
93     char sin_zero[8];
94 };
95
96
97 struct sockaddr {
98         unsigned char   sa_len;         /* bsd only total length */
99         sa_family_t     sa_family;      /* address family */
100         char            sa_data[14];    /* actually longer; address value */
101 };
102
103 /*
104  * Message header for recvmsg and sendmsg calls.
105  * Used value-result for recvmsg, value only for sendmsg.
106  */ 
107 struct msghdr {
108     void        *msg_name;      /* optional address */
109     socklen_t    msg_namelen;       /* size of address */
110     struct iovec    *msg_iov;       /* scatter/gather array */
111     int      msg_iovlen;        /* # elements in msg_iov */
112     void        *msg_control;       /* ancillary data, see below */
113     socklen_t    msg_controllen;    /* ancillary data buffer len */
114     int      msg_flags;     /* flags on received message */
115 };
116
117
118 /* Socket-level options for `getsockopt' and `setsockopt'.  */
119 enum
120   {
121     SO_DEBUG = 0x0001,          /* Record debugging information.  */
122 #define SO_DEBUG SO_DEBUG
123     SO_ACCEPTCONN = 0x0002,     /* Accept connections on socket.  */
124 #define SO_ACCEPTCONN SO_ACCEPTCONN
125     SO_REUSEADDR = 0x0004,      /* Allow reuse of local addresses.  */
126 #define SO_REUSEADDR SO_REUSEADDR
127     SO_KEEPALIVE = 0x0008,      /* Keep connections alive and send
128                                    SIGPIPE when they die.  */
129 #define SO_KEEPALIVE SO_KEEPALIVE
130     SO_DONTROUTE = 0x0010,      /* Don't do local routing.  */
131 #define SO_DONTROUTE SO_DONTROUTE
132     SO_BROADCAST = 0x0020,      /* Allow transmission of
133                                    broadcast messages.  */
134 #define SO_BROADCAST SO_BROADCAST
135     SO_USELOOPBACK = 0x0040,    /* Use the software loopback to avoid
136                                    hardware use when possible.  */
137 #define SO_USELOOPBACK SO_USELOOPBACK
138     SO_LINGER = 0x0080,         /* Block on close of a reliable
139                                    socket to transmit pending data.  */
140 #define SO_LINGER SO_LINGER
141     SO_OOBINLINE = 0x0100,      /* Receive out-of-band data in-band.  */
142 #define SO_OOBINLINE SO_OOBINLINE
143     SO_REUSEPORT = 0x0200,      /* Allow local address and port reuse.  */
144 #define SO_REUSEPORT SO_REUSEPORT
145     SO_SNDBUF = 0x1001,         /* Send buffer size.  */
146 #define SO_SNDBUF SO_SNDBUF
147     SO_RCVBUF = 0x1002,         /* Receive buffer.  */
148 #define SO_RCVBUF SO_RCVBUF
149     SO_SNDLOWAT = 0x1003,       /* Send low-water mark.  */
150 #define SO_SNDLOWAT SO_SNDLOWAT
151     SO_RCVLOWAT = 0x1004,       /* Receive low-water mark.  */
152 #define SO_RCVLOWAT SO_RCVLOWAT
153     SO_SNDTIMEO = 0x1005,       /* Send timeout.  */
154 #define SO_SNDTIMEO SO_SNDTIMEO
155     SO_RCVTIMEO = 0x1006,       /* Receive timeout.  */
156 #define SO_RCVTIMEO SO_RCVTIMEO
157     SO_ERROR = 0x1007,          /* Get and clear error status.  */
158 #define SO_ERROR SO_ERROR
159     SO_STYLE = 0x1008,          /* Get socket connection style.  */
160 #define SO_STYLE SO_STYLE
161     SO_TYPE = SO_STYLE          /* Compatible name for SO_STYLE.  */
162 #define SO_TYPE SO_TYPE
163   };
164 #define SO_INHERITED   (SO_REUSEADDR|SO_KEEPALIVE|SO_LINGER)
165
166 extern struct kmem_cache *sock_kcache;
167 extern struct kmem_cache *mbuf_kcache;
168 extern struct kmem_cache *udp_pcb_kcache;
169 extern struct kmem_cache *tcp_pcb_kcache;
170 extern struct kmem_cache *tcp_pcb_listen_kcache;
171 extern struct kmem_cache *tcp_segment_kcache;
172
173
174 void socket_init();
175 intreg_t send_iov(struct socket* sock, struct iovec* iov, int flags);
176 int send_datagram(struct socket* sock, struct iovec* iov, int flags);
177
178 intreg_t sys_socket(struct proc *p, int socket_family, int socket_type, int protocol);
179 intreg_t sys_sendto(struct proc *p, int socket, const void *buffer, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len);
180 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);
181 intreg_t sys_select(struct proc *p, int nfds, fd_set *readfds, fd_set *writefds,
182                                 fd_set *exceptfds, struct timeval *timeout);
183 intreg_t sys_connect(struct proc *p, int sockfd, const struct sockaddr *addr, socklen_t addrlen);
184 intreg_t sys_send(struct proc *p, int sockfd, const void *buf, size_t len, int flags);
185 intreg_t sys_recv(struct proc *p, int sockfd, void *buf, size_t len, int flags);
186 intreg_t sys_bind(struct proc* p, int sockfd, const struct sockaddr *addr, socklen_t addrlen);
187 intreg_t sys_accept(struct proc *p, int sockfd, struct sockaddr *addr, socklen_t *addrlen);
188 intreg_t sys_listen(struct proc *p, int sockfd, int backlog);
189
190
191 #endif /* ROS_SOCKET_H */
192