1/*********************************************************************
2   PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
3   See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
4
5 *********************************************************************/
6#ifndef INCLUDE_PICO_SOCKET
7#define INCLUDE_PICO_SOCKET
8#include "pico_queue.h"
9#include "pico_addressing.h"
10#include "pico_config.h"
11#include "pico_protocol.h"
12#include "pico_tree.h"
13
14#ifdef __linux__
15    #define PICO_DEFAULT_SOCKETQ (16 * 1024) /* Linux host, so we want full throttle */
16#else
17    #define PICO_DEFAULT_SOCKETQ (6 * 1024) /* seems like an acceptable default for small embedded systems */
18#endif
19
20#define PICO_SHUT_RD   1
21#define PICO_SHUT_WR   2
22#define PICO_SHUT_RDWR 3
23
24#ifdef PICO_SUPPORT_IPV4
25# define IS_SOCK_IPV4(s) ((s->net == &pico_proto_ipv4))
26#else
27# define IS_SOCK_IPV4(s) (0)
28#endif
29
30#ifdef PICO_SUPPORT_IPV6
31# define IS_SOCK_IPV6(s) ((s->net == &pico_proto_ipv6))
32#else
33# define IS_SOCK_IPV6(s) (0)
34#endif
35
36
37struct pico_sockport
38{
39    struct pico_tree socks; /* how you make the connection ? */
40    uint16_t number;
41    uint16_t proto;
42};
43
44
45struct pico_socket {
46    struct pico_protocol *proto;
47    struct pico_protocol *net;
48
49    union pico_address local_addr;
50    union pico_address remote_addr;
51
52    uint16_t local_port;
53    uint16_t remote_port;
54
55    struct pico_queue q_in;
56    struct pico_queue q_out;
57
58    void (*wakeup)(uint16_t ev, struct pico_socket *s);
59
60
61#ifdef PICO_SUPPORT_TCP
62    /* For the TCP backlog queue */
63    struct pico_socket *backlog;
64    struct pico_socket *next;
65    struct pico_socket *parent;
66    uint16_t max_backlog;
67    uint16_t number_of_pending_conn;
68#endif
69#ifdef PICO_SUPPORT_MCAST
70    struct pico_tree *MCASTListen;
71#ifdef PICO_SUPPORT_IPV6
72    struct pico_tree *MCASTListen_ipv6;
73#endif
74#endif
75    uint16_t ev_pending;
76
77    struct pico_device *dev;
78
79    /* Private field. */
80    int id;
81    uint16_t state;
82    uint16_t opt_flags;
83    pico_time timestamp;
84    void *priv;
85};
86
87struct pico_remote_endpoint {
88    union pico_address remote_addr;
89    uint16_t remote_port;
90};
91
92
93struct pico_ip_mreq {
94    union pico_address mcast_group_addr;
95    union pico_address mcast_link_addr;
96};
97struct pico_ip_mreq_source {
98    union pico_address mcast_group_addr;
99    union pico_address mcast_source_addr;
100    union pico_address mcast_link_addr;
101};
102
103
104#define PICO_SOCKET_STATE_UNDEFINED       0x0000u
105#define PICO_SOCKET_STATE_SHUT_LOCAL      0x0001u
106#define PICO_SOCKET_STATE_SHUT_REMOTE     0x0002u
107#define PICO_SOCKET_STATE_BOUND           0x0004u
108#define PICO_SOCKET_STATE_CONNECTED       0x0008u
109#define PICO_SOCKET_STATE_CLOSING         0x0010u
110#define PICO_SOCKET_STATE_CLOSED          0x0020u
111
112# define PICO_SOCKET_STATE_TCP                0xFF00u
113# define PICO_SOCKET_STATE_TCP_UNDEF          0x00FFu
114# define PICO_SOCKET_STATE_TCP_CLOSED         0x0100u
115# define PICO_SOCKET_STATE_TCP_LISTEN         0x0200u
116# define PICO_SOCKET_STATE_TCP_SYN_SENT       0x0300u
117# define PICO_SOCKET_STATE_TCP_SYN_RECV       0x0400u
118# define PICO_SOCKET_STATE_TCP_ESTABLISHED    0x0500u
119# define PICO_SOCKET_STATE_TCP_CLOSE_WAIT     0x0600u
120# define PICO_SOCKET_STATE_TCP_LAST_ACK       0x0700u
121# define PICO_SOCKET_STATE_TCP_FIN_WAIT1      0x0800u
122# define PICO_SOCKET_STATE_TCP_FIN_WAIT2      0x0900u
123# define PICO_SOCKET_STATE_TCP_CLOSING        0x0a00u
124# define PICO_SOCKET_STATE_TCP_TIME_WAIT      0x0b00u
125# define PICO_SOCKET_STATE_TCP_ARRAYSIZ       0x0cu
126
127
128/* Socket options */
129# define PICO_TCP_NODELAY                     1
130# define PICO_SOCKET_OPT_TCPNODELAY           0x0000u
131
132# define PICO_IP_MULTICAST_EXCLUDE            0
133# define PICO_IP_MULTICAST_INCLUDE            1
134# define PICO_IP_MULTICAST_IF                 32
135# define PICO_IP_MULTICAST_TTL                33
136# define PICO_IP_MULTICAST_LOOP               34
137# define PICO_IP_ADD_MEMBERSHIP               35
138# define PICO_IP_DROP_MEMBERSHIP              36
139# define PICO_IP_UNBLOCK_SOURCE               37
140# define PICO_IP_BLOCK_SOURCE                 38
141# define PICO_IP_ADD_SOURCE_MEMBERSHIP        39
142# define PICO_IP_DROP_SOURCE_MEMBERSHIP       40
143
144# define PICO_SOCKET_OPT_MULTICAST_LOOP       1
145# define PICO_SOCKET_OPT_KEEPIDLE              4
146# define PICO_SOCKET_OPT_KEEPINTVL             5
147# define PICO_SOCKET_OPT_KEEPCNT               6
148
149#define PICO_SOCKET_OPT_LINGER                13
150
151# define PICO_SOCKET_OPT_RCVBUF               52
152# define PICO_SOCKET_OPT_SNDBUF               53
153
154
155/* Constants */
156# define PICO_IP_DEFAULT_MULTICAST_TTL        1
157# define PICO_IP_DEFAULT_MULTICAST_LOOP       1
158
159#define PICO_SOCKET_TIMEOUT                   5000u /* 5 seconds */
160#define PICO_SOCKET_LINGER_TIMEOUT            3000u /* 3 seconds */
161#define PICO_SOCKET_BOUND_TIMEOUT             30000u /* 30 seconds */
162
163#define PICO_SOCKET_SHUTDOWN_WRITE 0x01u
164#define PICO_SOCKET_SHUTDOWN_READ  0x02u
165#define TCPSTATE(s) ((s)->state & PICO_SOCKET_STATE_TCP)
166
167#define PICO_SOCK_EV_RD 1u
168#define PICO_SOCK_EV_WR 2u
169#define PICO_SOCK_EV_CONN 4u
170#define PICO_SOCK_EV_CLOSE 8u
171#define PICO_SOCK_EV_FIN 0x10u
172#define PICO_SOCK_EV_ERR 0x80u
173
174struct pico_msginfo {
175    struct pico_device *dev;
176    uint8_t ttl;
177    uint8_t tos;
178};
179
180struct pico_socket *pico_socket_open(uint16_t net, uint16_t proto, void (*wakeup)(uint16_t ev, struct pico_socket *s));
181
182int pico_socket_read(struct pico_socket *s, void *buf, int len);
183int pico_socket_write(struct pico_socket *s, const void *buf, int len);
184
185int pico_socket_sendto(struct pico_socket *s, const void *buf, int len, void *dst, uint16_t remote_port);
186int pico_socket_sendto_extended(struct pico_socket *s, const void *buf, const int len,
187                                void *dst, uint16_t remote_port, struct pico_msginfo *msginfo);
188
189int pico_socket_recvfrom(struct pico_socket *s, void *buf, int len, void *orig, uint16_t *local_port);
190int pico_socket_recvfrom_extended(struct pico_socket *s, void *buf, int len, void *orig,
191                                  uint16_t *remote_port, struct pico_msginfo *msginfo);
192
193int pico_socket_send(struct pico_socket *s, const void *buf, int len);
194int pico_socket_recv(struct pico_socket *s, void *buf, int len);
195
196int pico_socket_bind(struct pico_socket *s, void *local_addr, uint16_t *port);
197int pico_socket_getname(struct pico_socket *s, void *local_addr, uint16_t *port, uint16_t *proto);
198int pico_socket_getpeername(struct pico_socket *s, void *remote_addr, uint16_t *port, uint16_t *proto);
199
200int pico_socket_connect(struct pico_socket *s, const void *srv_addr, uint16_t remote_port);
201int pico_socket_listen(struct pico_socket *s, const int backlog);
202struct pico_socket *pico_socket_accept(struct pico_socket *s, void *orig, uint16_t *port);
203int8_t pico_socket_del(struct pico_socket *s);
204
205int pico_socket_setoption(struct pico_socket *s, int option, void *value);
206int pico_socket_getoption(struct pico_socket *s, int option, void *value);
207
208int pico_socket_shutdown(struct pico_socket *s, int mode);
209int pico_socket_close(struct pico_socket *s);
210
211struct pico_frame *pico_socket_frame_alloc(struct pico_socket *s, struct pico_device *dev, uint16_t len);
212struct pico_device *get_sock_dev(struct pico_socket *s);
213
214
215#ifdef PICO_SUPPORT_IPV4
216# define is_sock_ipv4(x) (x->net == &pico_proto_ipv4)
217#else
218# define is_sock_ipv4(x) (0)
219#endif
220
221#ifdef PICO_SUPPORT_IPV6
222# define is_sock_ipv6(x) (x->net == &pico_proto_ipv6)
223#else
224# define is_sock_ipv6(x) (0)
225#endif
226
227#ifdef PICO_SUPPORT_UDP
228# define is_sock_udp(x) (x->proto == &pico_proto_udp)
229#else
230# define is_sock_udp(x) (0)
231#endif
232
233#ifdef PICO_SUPPORT_TCP
234# define is_sock_tcp(x) (x->proto == &pico_proto_tcp)
235#else
236# define is_sock_tcp(x) (0)
237#endif
238
239/* Interface towards transport protocol */
240int pico_transport_process_in(struct pico_protocol *self, struct pico_frame *f);
241struct pico_socket *pico_socket_clone(struct pico_socket *facsimile);
242int8_t pico_socket_add(struct pico_socket *s);
243int pico_transport_error(struct pico_frame *f, uint8_t proto, int code);
244
245/* Socket loop */
246int pico_sockets_loop(int loop_score);
247struct pico_socket*pico_sockets_find(uint16_t local, uint16_t remote);
248/* Port check */
249int pico_is_port_free(uint16_t proto, uint16_t port, void *addr, void *net);
250
251struct pico_sockport *pico_get_sockport(uint16_t proto, uint16_t port);
252
253uint32_t pico_socket_get_mss(struct pico_socket *s);
254int pico_socket_set_family(struct pico_socket *s, uint16_t family);
255
256int pico_count_sockets(uint8_t proto);
257
258#define PICO_SOCKET_SETOPT_EN(socket, index)  (socket->opt_flags |=  (1 << index))
259#define PICO_SOCKET_SETOPT_DIS(socket, index) (socket->opt_flags &= (uint16_t) ~(1 << index))
260#define PICO_SOCKET_GETOPT(socket, index) ((socket->opt_flags & (1u << index)) != 0)
261
262
263#endif
264