1 #ifndef __MTCP_API_H_
2 #define __MTCP_API_H_
3 
4 #include <stdint.h>
5 #include <netinet/in.h>
6 #include <sys/uio.h>
7 
8 #ifndef UNUSED
9 #define UNUSED(x)		(void)x
10 #endif
11 
12 #ifndef INPORT_ANY
13 #define INPORT_ANY	(uint16_t)0
14 #endif
15 
16 typedef unsigned char byte;
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 /** mTCP context */
23 struct mtcp_context
24 {
25 	int cpu;
26 };
27 
28 typedef struct mtcp_context *mctx_t;
29 
30 /** mTCP signal handler type */
31 typedef void (*mtcp_sighandler_t)(int);
32 
33 /** Socket types */
34 enum socket_type
35 {
36 	/** unused */
37 	MOS_SOCK_UNUSED,
38 
39 	/* listening socket type */
40 	/** regular mTCP connection listen socket */
41 	MOS_SOCK_STREAM_LISTEN,
42 	/** MOS proxy socket listening socket */
43 	/* (pending implementation) */
44 	MOS_SOCK_PROXY_LISTEN,
45 	/** MOS monitor socket listening socket */
46 	MOS_SOCK_MONITOR_STREAM,
47 
48 	/* stream socket type */
49 
50 	/** regular mTCP connection socket */
51 	MOS_SOCK_STREAM,
52 	/** MOS proxy socket */
53 	/* (pending implementation) */
54 	MOS_SOCK_PROXY,
55 	/** MOS monitor socket */
56 	MOS_SOCK_MONITOR_STREAM_ACTIVE,
57 	/** MOS monitor socket (raw, stateless) */
58 	MOS_SOCK_MONITOR_RAW,
59 
60 	/* for epoll */
61 	MOS_SOCK_EPOLL,
62 	/* for pipe */
63 	MOS_SOCK_PIPE,
64 };
65 
66 /* Configurable mTCP attributes
67  * This is automatically generated by mOS core after the
68  * mtcp_init() function call. You can change this option
69  * in your program using mtcp_get/set_conf().
70  */
71 struct mtcp_conf
72 {
73 /** Maximum length of application name */
74 #define APP_NAME_LEN 			40
75 /** Maximum concurrently runable application */
76 #define MOS_APP 			20
77 
78 	int num_cores;        /**< number of cores to use */
79 	int max_concurrency;  /**< number of concurrent flows per core*/
80 	uint64_t cpu_mask;
81 
82 	int max_num_buffers;  /**< number of socket buffers */
83 	int rcvbuf_size;      /**< size of receive buffer */
84 	int sndbuf_size;      /**< size of send buffer */
85 
86 	int tcp_timewait;     /**< time wait time in sec */
87 	int tcp_timeout;      /**< timeout in sec, -1 for not to check timeout */
88 
89 #define MOS_APP_ARGC 20
90 	uint64_t app_cpu_mask[MOS_APP];
91 	char *app_argv[MOS_APP][MOS_APP_ARGC];
92 	int app_argc[MOS_APP];
93 	int num_app;                     /**< number of registered apps */
94 };
95 
96 /* Target to modify */
97 struct app_context
98 {
99 	mctx_t mctx;              /**< mTCP context */
100 	int socket_id;            /**< listing socket ID */
101 	struct conn_filter *cf;
102 	int ep_id;
103 };
104 
105 /* Application need to specify those parameters. */
106 /* NOTE: This structure is not used in mos_release 0.2a
107  * This structure will be used by embedded mOS application using
108  * mOS server.
109  */
110 struct app_ops
111 {
112 	/** Initialization function which is called for only once per each
113 	 * application */
114 	void (*app_init)(int argc, char **argv);
115 	/** Initialization function which is called for each CPU core */
116 	void (*thread_init)(mctx_t mctx, void **app_ctx);
117 	/** Function contains code which will be executed after initialization
118 	 * phase */
119 	void (*run)(mctx_t mctx, void **app_ctx);
120 	/* is the application enabled at the moment? */
121 	int enable;
122 };
123 
124 
125 /** Initialize mOS context with parameters mentioned in the config file
126  * @param [in] config_file: location of config file
127  * @return 0 on success, -1 on error
128  *
129  * Setting dpdk devices, interface, load configuration from config file,
130  * routing table, arp table, etc.
131  */
132 int
133 mtcp_init(const char *config_file);
134 
135 /** Destroy the global mOS context
136  * @return 0 on success, -1 on error
137  */
138 int
139 mtcp_destroy();
140 
141 /** Load current mtcp configuration in *conf
142  * @param [out] conf: configurations
143  * @return 0 on success, -1 on error
144  */
145 int
146 mtcp_getconf(struct mtcp_conf *conf);
147 
148 /** Update mOS base with parameters mentioned in *conf
149  * @param [in] conf: configurations to set
150  * @return 0 on success, -1 on error
151  */
152 int
153 mtcp_setconf(const struct mtcp_conf *conf);
154 
155 /** Bind a thread to a specific CPU core
156  * @param [in] cpu: CPU ID
157  * @return 0 on success, -1 on error
158  */
159 int
160 mtcp_core_affinitize(int cpu);
161 
162 /** Create mOS/mtcp context thread based on the parameters passed
163  * by mtcp_init() & mtcp_setconf() functions
164  * @param [in] cpu: Core id to affinitize new mtcp thread
165  * @return mtcp context, NULL on error
166  */
167 mctx_t
168 mtcp_create_context(int cpu);
169 
170 /** Destory mtcp context that was created by mOS/mTCP thread
171  * @param [in] mctx: mtcp context
172  * @return 0 on success, -1 on error
173  */
174 int
175 mtcp_destroy_context(mctx_t mctx);
176 
177 /** Register signal handler (mtcp_sighandler_t handler )
178  * for int signum
179  * @param [in] signum: Signal number to handle
180  * @param [in] handler: Handler function
181  * @return Same handler as input
182  */
183 mtcp_sighandler_t
184 mtcp_register_signal(int signum, mtcp_sighandler_t handler);
185 
186 /** Create pipe
187  * @param [in] mctx: mtcp context
188  * @param [out] pipeid: created pipe
189  * @return 0 on success, -1 on error
190  */
191 int
192 mtcp_pipe(mctx_t mctx, int pipeid[2]);
193 
194 /** Get socket options
195  *
196  * <ol>
197  *
198  * <li> Please see http://mos.kaist.edu/man/mtcp_getsockopt.html for
199  * the further informations. </li>
200  *
201  * <li> MOS_FRAGINFO_CLIBUF and MOS_FRAGINFO_SVRBUF \n
202  * Gives back offsets to fragments (non-contiguous data segments) currently
203  * stored in client’s TCP ring buffer. The optval is an array of
204  * `struct tcp_ring_fragment`
205  * where offset flow data starting from client’s TCP SYN sequence number,
206  * and len is the length of the tcp_ring_fragment. The optval holds the size
207  * of the array (in terms of the number of elements). </li>
208  *
209  * <li> MOS_INFO_CLIBUF and MOS_INFO_SVRBUF \n
210  * Returns meta-data regarding the client’s TCP ring buffer. This information
211  * is returned in the form of optval which is passed as struct tcp_buf_info. </li>
212  *
213  * <li> MOS_TCP_STATE_CLI and MOS_TCP_STATE_SVR \n
214  * Returns the current emulated state of the client. The optval argument is
215  * a pointer to an int whereas the optlen argument contains the sizeof(int).
216  * The optval returns a value of type enum tcpstate which can carry any one
217  * of the following states. </li>
218  * </ol>
219  *
220  * @param [in] mctx: mtcp context
221  * @param [in] sock: socket id
222  * @param [in] level: SOL_MONSOCKET
223  * @param [in] optname: __variable__
224  * @param [out] optval: value of getting option
225  * @param [out] optlen: length of getting option
226  * @return Zero on success, -1 on error
227  */
228 int
229 mtcp_getsockopt(mctx_t mctx, int sock, int level,
230 		int optname, void *optval, socklen_t *optlen);
231 
232 /** Set socket options
233  *
234  * <ol>
235  *
236  * <li> MOS_CLIBUF and MOS_SVRBUF \n
237  * Dynamically adjust the size of the TCP receive ring buffer of the
238  * emulated client/server stack. The optval contains the size of the buffer
239  * that needs to be set as int, while optlen is equal to sizeof(int). </li>
240  *
241  * <li> MOS_CLIOVERLAP and MOS_SVROVERLAP \n
242  * Dynamically determine the policy on content overlap (e.g., overwriting
243  * with the retransmitted payload or not) for the client-side buffer. The
244  * optval can be either MOS_OVERLAP_POLICY_FIRST (to take the first data
245  * and never overwrite the buffer) or MOS_OVERLAP_POLICY_LAST (to always
246  * update the buffer with the last data), and optlen is equal to sizeof(int). </li>
247  *
248  * <li> MOS_STOP_MON \n
249  * Dynamically stop monitoring a flow for the specific side. This option can
250  * be used only with a MOS_SOCK_MONITOR_ACTIVE socket, which is given as a
251  * parameter in callback functions for every flow. The optval contains a side
252  * variable (MOS_SIDE_CLI, MOS_SIDE_SVR, or MOS_SIDE_BOTH), while optlen is
253  * equal to sizeof(int). </li>
254  *
255  * </ol>
256  *
257  * @param [in] mctx: mtcp context
258  * @param [in] sock: socket id
259  * @param [in] level: SOL_MONSOCKET
260  * @param [in] optname: __variable__
261  * @param [in] optval: value of setting option
262  * @param [in] optlen: length of setting option
263  * @return Zero on success, -1 on error
264  */
265 int
266 mtcp_setsockopt(mctx_t mctx, int sock, int level,
267 		int optname, const void *optval, socklen_t optlen);
268 
269 /** Set socket as nonblock
270  * @param [in] mctx: mtcp context
271  * @param [in] sock: socket id
272  * @return Zero on success, -1 on error
273  *
274  * DEPRECATED
275  */
276 int
277 mtcp_setsock_nonblock(mctx_t mctx, int sock);
278 
279 /** Control socket
280  * @param [in] mctx: mtcp context
281  * @param [in] sock: socket id
282  * @param [in] request: requested operation
283  * @param [in,out] argp: pointer to argument
284  * @return Zero on success, -1 on error
285  *
286  * Operations | Description
287  * ---------- | -----------
288  * FIONREAD   | number of data bytes in receive buffer
289  * FIONBIO    | for non-blocking I/O
290  */
291 int
292 mtcp_ioctl(mctx_t mctx, int sock, int request, void *argp);
293 
294 /** Create a socket
295  * @param [in] mctx: mtcp context
296  * @param [in] domain: AF_INET, Not used
297  * @param [in] type: Any of the following keyword
298  *             - MOS_SOCK_STREAM (End TCP)
299  *             - MOS_SOCK_MONITOR_RAW (Packet-level monitor)
300  *             - MOS_SOCK_MONITOR_STREAM (Flow-level monitor)
301  *              (MOS_SOCK_PROXY: To be supported)
302  * @param [in] protocol: NULL, Not used
303  * @return Zero on success, -1 on error
304  */
305 int
306 mtcp_socket(mctx_t mctx, int domain, int type, int protocol);
307 
308 /** Bind a socket, same as `bind()`
309  * @return Zero on success, -1 on error
310  */
311 int
312 mtcp_bind(mctx_t mctx, int sock,
313 		const struct sockaddr *addr, socklen_t addrlen);
314 
315 /** Listen a listening socket, same as `listen()`
316  * @return Zero on success, -1 on error
317  *
318  * Only MOS_SOCK_LISTENER, MOS_SOCK_PROXY are allowed
319  */
320 int
321 mtcp_listen(mctx_t mctx, int sock, int backlog);
322 
323 /** Accept new flow, same as `accept()`
324  * @param [in] mctx: mtcp context
325  * @param [in] sock: socket id for MOS_SOCK_STREAM
326  * @param [in] addr: address of the peer host(s)
327  * @param [in] addrlen: length of `addr`
328  * @return Zero on success, -1 on error
329  */
330 int
331 mtcp_accept(mctx_t mctx, int sock, struct sockaddr *addr, socklen_t *addrlen);
332 
333 /** Initialize RSS pool for decide appropriate port numbers
334  * @param [in] mctx: mtcp context
335  * @param [in] saddr_base: source IP address base
336  * @param [in] num_addr: number of source IP address to use
337  * @param [in] daddr: destination IP address
338  * @param [in] dport: destination port number
339  * @return Zero on success, -1 on error
340  *
341  * w.r.t source IP addr, destination IP addr, destination port
342  */
343 int
344 mtcp_init_rss(mctx_t mctx, in_addr_t saddr_base, int num_addr,
345 		in_addr_t daddr, in_addr_t dport);
346 
347 /** Connect new flow, same as `connect()`
348  * @return Zero on success, -1 on error
349  */
350 int
351 mtcp_connect(mctx_t mctx, int sock,
352 		const struct sockaddr *addr, socklen_t addrlen);
353 
354 /** Close flow, same as `close()`
355  * @return Zero on success, -1 on error
356  */
357 int
358 mtcp_close(mctx_t mctx, int sock);
359 
360 /** Abort flow by sending RST
361  * @return Zero on success, -1 on error
362  *
363  * Different from `mtcp_close()` which processes 4way handshake by FIN
364  */
365 int
366 mtcp_abort(mctx_t mctx, int sock);
367 
368 /** Returns the current address to which the socket sockfd is bound
369  * @param [in] mctx: mtcp context
370  * @param [in] addr: address buffer to be filled
371  * @param [in] addrlen: amount of space pointed to by addr
372  * @return 0 on success, -1 on error
373  */
374 int
375 mtcp_getsockname(mctx_t mctx, int sock, struct sockaddr *addr, socklen_t *addrlen);
376 
377 /** Read byte stream from flow, same as `recv()`
378  * For now, it can only accept flags 0 (default aka mtcp_read()) & MSG_PEEK
379  * @return number of bytes read on success, -1 on error
380  */
381 ssize_t
382 mtcp_recv(mctx_t mctx, int sockid, char *buf, size_t len, int flags);
383 
384 /** Read byte stream from flow, same as `read()`
385  * @return number of bytes read on success, -1 on error
386  */
387 ssize_t
388 mtcp_read(mctx_t mctx, int sock, char *buf, size_t len);
389 
390 /* readv should work in atomic */
391 /** Read byte stream from flow in vector, same as `readv()`
392  * @return number of bytes read on success, -1 on error
393  */
394 ssize_t
395 mtcp_readv(mctx_t mctx, int sock, const struct iovec *iov, int numIOV);
396 
397 /** Write byte stream to flow, same as `write()`
398  * @return number of bytes write on success, -1 on error
399  */
400 ssize_t
401 mtcp_write(mctx_t mctx, int sock, const char *buf, size_t len);
402 
403 /* writev should work in atomic */
404 /** Write byte stream to flow in vector, same as `writev()`
405  * @return number of bytes write on success, -1 on error
406  */
407 ssize_t
408 mtcp_writev(mctx_t mctx, int sock, const struct iovec *iov, int numIOV);
409 
410 /** Get concurrent flow count of the underlying mtcp manager context (per-thread)
411  * @param [in] mctx: mtcp context
412  * @return concurrent flow count
413  */
414 uint32_t
415 mtcp_get_connection_cnt(mctx_t mctx);
416 
417 #ifdef __cplusplus
418 };
419 #endif
420 
421 #endif /* __MTCP_API_H_ */
422