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 };
121 
122 
123 /** Initialize mOS context with parameters mentioned in the config file
124  * @param [in] config_file: location of config file
125  * @return 0 on success, -1 on error
126  *
127  * Setting dpdk devices, interface, load configuration from config file,
128  * routing table, arp table, etc.
129  */
130 int
131 mtcp_init(const char *config_file);
132 
133 /** Destroy the global mOS context
134  * @return 0 on success, -1 on error
135  */
136 int
137 mtcp_destroy();
138 
139 /** Load current mtcp configuration in *conf
140  * @param [out] conf: configurations
141  * @return 0 on success, -1 on error
142  */
143 int
144 mtcp_getconf(struct mtcp_conf *conf);
145 
146 /** Update mOS base with parameters mentioned in *conf
147  * @param [in] conf: configurations to set
148  * @return 0 on success, -1 on error
149  */
150 int
151 mtcp_setconf(const struct mtcp_conf *conf);
152 
153 /** Bind a thread to a specific CPU core
154  * @param [in] cpu: CPU ID
155  * @return 0 on success, -1 on error
156  */
157 int
158 mtcp_core_affinitize(int cpu);
159 
160 /** Create mOS/mtcp context thread based on the parameters passed
161  * by mtcp_init() & mtcp_setconf() functions
162  * @param [in] cpu: Core id to affinitize new mtcp thread
163  * @return mtcp context, NULL on error
164  */
165 mctx_t
166 mtcp_create_context(int cpu);
167 
168 /** Destory mtcp context that was created by mOS/mTCP thread
169  * @param [in] mctx: mtcp context
170  * @return 0 on success, -1 on error
171  */
172 int
173 mtcp_destroy_context(mctx_t mctx);
174 
175 /** Register signal handler (mtcp_sighandler_t handler )
176  * for int signum
177  * @param [in] signum: Signal number to handle
178  * @param [in] handler: Handler function
179  * @return Same handler as input
180  */
181 mtcp_sighandler_t
182 mtcp_register_signal(int signum, mtcp_sighandler_t handler);
183 
184 /** Create pipe
185  * @param [in] mctx: mtcp context
186  * @param [out] pipeid: created pipe
187  * @return 0 on success, -1 on error
188  */
189 int
190 mtcp_pipe(mctx_t mctx, int pipeid[2]);
191 
192 /** Get socket options
193  *
194  * <ol>
195  *
196  * <li> Please see http://mos.kaist.edu/man/mtcp_getsockopt.html for
197  * the further informations. </li>
198  *
199  * <li> MOS_FRAGINFO_CLIBUF and MOS_FRAGINFO_SVRBUF \n
200  * Gives back offsets to fragments (non-contiguous data segments) currently
201  * stored in client’s TCP ring buffer. The optval is an array of
202  * `struct tcp_ring_fragment`
203  * where offset flow data starting from client’s TCP SYN sequence number,
204  * and len is the length of the tcp_ring_fragment. The optval holds the size
205  * of the array (in terms of the number of elements). </li>
206  *
207  * <li> MOS_INFO_CLIBUF and MOS_INFO_SVRBUF \n
208  * Returns meta-data regarding the client’s TCP ring buffer. This information
209  * is returned in the form of optval which is passed as struct tcp_buf_info. </li>
210  *
211  * <li> MOS_TCP_STATE_CLI and MOS_TCP_STATE_SVR \n
212  * Returns the current emulated state of the client. The optval argument is
213  * a pointer to an int whereas the optlen argument contains the sizeof(int).
214  * The optval returns a value of type enum tcpstate which can carry any one
215  * of the following states. </li>
216  * </ol>
217  *
218  * @param [in] mctx: mtcp context
219  * @param [in] sock: socket id
220  * @param [in] level: SOL_MONSOCKET
221  * @param [in] optname: __variable__
222  * @param [out] optval: value of getting option
223  * @param [out] optlen: length of getting option
224  * @return Zero on success, -1 on error
225  */
226 int
227 mtcp_getsockopt(mctx_t mctx, int sock, int level,
228 		int optname, void *optval, socklen_t *optlen);
229 
230 /** Set socket options
231  *
232  * <ol>
233  *
234  * <li> MOS_CLIBUF and MOS_SVRBUF \n
235  * Dynamically adjust the size of the TCP receive ring buffer of the
236  * emulated client/server stack. The optval contains the size of the buffer
237  * that needs to be set as int, while optlen is equal to sizeof(int). </li>
238  *
239  * <li> MOS_CLIOVERLAP and MOS_SVROVERLAP \n
240  * Dynamically determine the policy on content overlap (e.g., overwriting
241  * with the retransmitted payload or not) for the client-side buffer. The
242  * optval can be either MOS_OVERLAP_POLICY_FIRST (to take the first data
243  * and never overwrite the buffer) or MOS_OVERLAP_POLICY_LAST (to always
244  * update the buffer with the last data), and optlen is equal to sizeof(int). </li>
245  *
246  * <li> MOS_STOP_MON \n
247  * Dynamically stop monitoring a flow for the specific side. This option can
248  * be used only with a MOS_SOCK_MONITOR_ACTIVE socket, which is given as a
249  * parameter in callback functions for every flow. The optval contains a side
250  * variable (MOS_SIDE_CLI, MOS_SIDE_SVR, or MOS_SIDE_BOTH), while optlen is
251  * equal to sizeof(int). </li>
252  *
253  * </ol>
254  *
255  * @param [in] mctx: mtcp context
256  * @param [in] sock: socket id
257  * @param [in] level: SOL_MONSOCKET
258  * @param [in] optname: __variable__
259  * @param [in] optval: value of setting option
260  * @param [in] optlen: length of setting option
261  * @return Zero on success, -1 on error
262  */
263 int
264 mtcp_setsockopt(mctx_t mctx, int sock, int level,
265 		int optname, const void *optval, socklen_t optlen);
266 
267 /** Set socket as nonblock
268  * @param [in] mctx: mtcp context
269  * @param [in] sock: socket id
270  * @return Zero on success, -1 on error
271  *
272  * DEPRECATED
273  */
274 int
275 mtcp_setsock_nonblock(mctx_t mctx, int sock);
276 
277 /** Control socket
278  * @param [in] mctx: mtcp context
279  * @param [in] sock: socket id
280  * @param [in] request: requested operation
281  * @param [in,out] argp: pointer to argument
282  * @return Zero on success, -1 on error
283  *
284  * Operations | Description
285  * ---------- | -----------
286  * FIONREAD   | number of data bytes in receive buffer
287  * FIONBIO    | for non-blocking I/O
288  */
289 int
290 mtcp_ioctl(mctx_t mctx, int sock, int request, void *argp);
291 
292 /** Create a socket
293  * @param [in] mctx: mtcp context
294  * @param [in] domain: AF_INET, Not used
295  * @param [in] type: Any of the following keyword
296  *             - MOS_SOCK_STREAM (End TCP)
297  *             - MOS_SOCK_MONITOR_RAW (Packet-level monitor)
298  *             - MOS_SOCK_MONITOR_STREAM (Flow-level monitor)
299  *              (MOS_SOCK_PROXY: To be supported)
300  * @param [in] protocol: NULL, Not used
301  * @return Zero on success, -1 on error
302  */
303 int
304 mtcp_socket(mctx_t mctx, int domain, int type, int protocol);
305 
306 /** Bind a socket, same as `bind()`
307  * @return Zero on success, -1 on error
308  */
309 int
310 mtcp_bind(mctx_t mctx, int sock,
311 		const struct sockaddr *addr, socklen_t addrlen);
312 
313 /** Listen a listening socket, same as `listen()`
314  * @return Zero on success, -1 on error
315  *
316  * Only MOS_SOCK_LISTENER, MOS_SOCK_PROXY are allowed
317  */
318 int
319 mtcp_listen(mctx_t mctx, int sock, int backlog);
320 
321 /** Accept new flow, same as `accept()`
322  * @param [in] mctx: mtcp context
323  * @param [in] sock: socket id for MOS_SOCK_STREAM
324  * @param [in] addr: address of the peer host(s)
325  * @param [in] addrlen: length of `addr`
326  * @return Zero on success, -1 on error
327  */
328 int
329 mtcp_accept(mctx_t mctx, int sock, struct sockaddr *addr, socklen_t *addrlen);
330 
331 /** Initialize RSS pool for decide appropriate port numbers
332  * @param [in] mctx: mtcp context
333  * @param [in] saddr_base: source IP address base
334  * @param [in] num_addr: number of source IP address to use
335  * @param [in] daddr: destination IP address
336  * @param [in] dport: destination port number
337  * @return Zero on success, -1 on error
338  *
339  * w.r.t source IP addr, destination IP addr, destination port
340  */
341 int
342 mtcp_init_rss(mctx_t mctx, in_addr_t saddr_base, int num_addr,
343 		in_addr_t daddr, in_addr_t dport);
344 
345 /** Connect new flow, same as `connect()`
346  * @return Zero on success, -1 on error
347  */
348 int
349 mtcp_connect(mctx_t mctx, int sock,
350 		const struct sockaddr *addr, socklen_t addrlen);
351 
352 /** Close flow, same as `close()`
353  * @return Zero on success, -1 on error
354  */
355 int
356 mtcp_close(mctx_t mctx, int sock);
357 
358 /** Abort flow by sending RST
359  * @return Zero on success, -1 on error
360  *
361  * Different from `mtcp_close()` which processes 4way handshake by FIN
362  */
363 int
364 mtcp_abort(mctx_t mctx, int sock);
365 
366 /** Returns the current address to which the socket sockfd is bound
367  * @param [in] mctx: mtcp context
368  * @param [in] addr: address buffer to be filled
369  * @param [in] addrlen: amount of space pointed to by addr
370  * @return 0 on success, -1 on error
371  */
372 int
373 mtcp_getsockname(mctx_t mctx, int sock, struct sockaddr *addr, socklen_t *addrlen);
374 
375 /** Read byte stream from flow, same as `recv()`
376  * For now, it can only accept flags 0 (default aka mtcp_read()) & MSG_PEEK
377  * @return number of bytes read on success, -1 on error
378  */
379 ssize_t
380 mtcp_recv(mctx_t mctx, int sockid, char *buf, size_t len, int flags);
381 
382 /** Read byte stream from flow, same as `read()`
383  * @return number of bytes read on success, -1 on error
384  */
385 inline ssize_t
386 mtcp_read(mctx_t mctx, int sock, char *buf, size_t len);
387 
388 /* readv should work in atomic */
389 /** Read byte stream from flow in vector, same as `readv()`
390  * @return number of bytes read on success, -1 on error
391  */
392 ssize_t
393 mtcp_readv(mctx_t mctx, int sock, const struct iovec *iov, int numIOV);
394 
395 /** Write byte stream to flow, same as `write()`
396  * @return number of bytes write on success, -1 on error
397  */
398 ssize_t
399 mtcp_write(mctx_t mctx, int sock, const char *buf, size_t len);
400 
401 /* writev should work in atomic */
402 /** Write byte stream to flow in vector, same as `writev()`
403  * @return number of bytes write on success, -1 on error
404  */
405 ssize_t
406 mtcp_writev(mctx_t mctx, int sock, const struct iovec *iov, int numIOV);
407 
408 /** Get concurrent flow count of the underlying mtcp manager context (per-thread)
409  * @param [in] mctx: mtcp context
410  * @return concurrent flow count
411  */
412 uint32_t
413 mtcp_get_connection_cnt(mctx_t mctx);
414 
415 #ifdef __cplusplus
416 };
417 #endif
418 
419 #endif /* __MTCP_API_H_ */
420