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