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