tcp_conn.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2001-2003 FhG Fokus
  5. *
  6. * This file is part of ser, a free SIP server.
  7. *
  8. * ser is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * For a license to use the ser software under conditions
  14. * other than those described here, or to purchase support for this
  15. * software, please contact iptel.org by e-mail at the following addresses:
  16. * [email protected]
  17. *
  18. * ser is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  26. *
  27. *
  28. * History:
  29. * --------
  30. * 2003-01-29 tcp buffer size ++-ed to allow for 0-terminator
  31. * 2003-06-30 added tcp_connection flags & state (andrei)
  32. * 2003-10-27 tcp port aliases support added (andrei)
  33. * 2006-10-13 added tcp_req_states for STUN (vlada)
  34. * 2007-07-26 improved tcp connection hash function; increased aliases
  35. * hash size (andrei)
  36. * 2007-11-26 switched to local_timer (andrei)
  37. * 2007-11-30 buffered write support (andrei)
  38. */
  39. #ifndef _tcp_conn_h
  40. #define _tcp_conn_h
  41. #include "tcp_init.h"
  42. #include "tcp_options.h"
  43. #include "ip_addr.h"
  44. #include "locking.h"
  45. #include "atomic_ops.h"
  46. #include "timer_ticks.h"
  47. #include "timer.h"
  48. /* maximum number of port aliases x search wildcard possibilities */
  49. #define TCP_CON_MAX_ALIASES (4*3)
  50. #define TCP_CHILD_TIMEOUT 5 /* after 5 seconds, the child "returns"
  51. the connection to the tcp master process */
  52. #define TCP_MAIN_SELECT_TIMEOUT 5 /* how often "tcp main" checks for timeout*/
  53. #define TCP_CHILD_SELECT_TIMEOUT 2 /* the same as above but for children */
  54. /* tcp connection flags */
  55. #define F_CONN_READ_W 2 /* watched for READ ev. in main */
  56. #define F_CONN_WRITE_W 4 /* watched for WRITE (main) */
  57. #define F_CONN_READER 8 /* handled by a tcp reader */
  58. #define F_CONN_HASHED 16 /* in tcp_main hash */
  59. #define F_CONN_FD_CLOSED 32 /* fd was already closed */
  60. #define F_CONN_PENDING 64 /* pending connect (fd not known yet in main) */
  61. #define F_CONN_MAIN_TIMER 128 /* timer active in the tcp_main process */
  62. #define F_CONN_EOF_SEEN 256 /* FIN or RST have been received */
  63. #define F_CONN_FORCE_EOF 512 /* act as if an EOF was received */
  64. #define F_CONN_OOB_DATA 1024 /* out of band data on the connection */
  65. #define F_CONN_WR_ERROR 2048 /* write error on the fd */
  66. #define F_CONN_WANTS_RD 4096 /* conn. should be watched for READ */
  67. #define F_CONN_WANTS_WR 8192 /* conn. should be watched for WRITE */
  68. #define F_CONN_PASSIVE 16384 /* conn. created via accept() and not connect()*/
  69. #ifndef NO_READ_HTTP11
  70. #define READ_HTTP11
  71. #endif
  72. #ifndef NO_READ_MSRP
  73. #define READ_MSRP
  74. #endif
  75. #ifndef NO_READ_WS
  76. #define READ_WS
  77. #endif
  78. enum tcp_req_errors { TCP_REQ_INIT, TCP_REQ_OK, TCP_READ_ERROR,
  79. TCP_REQ_OVERRUN, TCP_REQ_BAD_LEN };
  80. enum tcp_req_states { H_SKIP_EMPTY, H_SKIP_EMPTY_CR_FOUND,
  81. H_SKIP_EMPTY_CRLF_FOUND, H_SKIP_EMPTY_CRLFCR_FOUND,
  82. H_SKIP, H_LF, H_LFCR, H_BODY, H_STARTWS,
  83. H_CONT_LEN1, H_CONT_LEN2, H_CONT_LEN3, H_CONT_LEN4, H_CONT_LEN5,
  84. H_CONT_LEN6, H_CONT_LEN7, H_CONT_LEN8, H_CONT_LEN9, H_CONT_LEN10,
  85. H_CONT_LEN11, H_CONT_LEN12, H_CONT_LEN13, H_L_COLON,
  86. H_CONT_LEN_BODY, H_CONT_LEN_BODY_PARSE,
  87. H_STUN_MSG, H_STUN_READ_BODY, H_STUN_FP, H_STUN_END, H_PING_CRLF
  88. #ifdef READ_HTTP11
  89. , H_HTTP11_CHUNK_START, H_HTTP11_CHUNK_SIZE,
  90. H_HTTP11_CHUNK_BODY, H_HTTP11_CHUNK_END, H_HTTP11_CHUNK_FINISH
  91. #endif
  92. #ifdef READ_MSRP
  93. , H_MSRP_BODY, H_MSRP_BODY_LF, H_MSRP_BODY_END, H_MSRP_FINISH
  94. #endif
  95. };
  96. enum tcp_conn_states { S_CONN_ERROR=-2, S_CONN_BAD=-1,
  97. S_CONN_OK=0, /* established (write or read) */
  98. S_CONN_INIT, /* initial state (invalid) */
  99. S_CONN_EOF,
  100. S_CONN_ACCEPT, S_CONN_CONNECT
  101. };
  102. /* fd communication commands */
  103. enum conn_cmds {
  104. CONN_DESTROY=-3 /* destroy connection & auto-dec. refcnt */,
  105. CONN_ERROR=-2 /* error on connection & auto-dec. refcnt */,
  106. CONN_EOF=-1 /* eof received or conn. closed & auto-dec refcnt */,
  107. CONN_NOP=0 /* do-nothing (invalid for tcp_main) */,
  108. CONN_RELEASE /* release a connection from tcp_read back into tcp_main
  109. & auto-dec refcnt */,
  110. CONN_GET_FD /* request a fd from tcp_main */,
  111. CONN_NEW /* update/set a fd int a new tcp connection; refcnts are
  112. not touched */,
  113. CONN_QUEUED_WRITE /* new write queue: start watching the fd for write &
  114. auto-dec refcnt */,
  115. CONN_NEW_PENDING_WRITE /* like CONN_NEW+CONN_QUEUED_WRITE: set fd and
  116. start watching it for write (write queue
  117. non-empty); refcnts are not touced */,
  118. CONN_NEW_COMPLETE /* like CONN_NEW_PENDING_WRITE, but there is no
  119. pending write (the write queue might be empty) */
  120. };
  121. /* CONN_RELEASE, EOF, ERROR, DESTROY can be used by "reader" processes
  122. * CONN_GET_FD, CONN_NEW*, CONN_QUEUED_WRITE only by writers */
  123. struct tcp_req{
  124. struct tcp_req* next;
  125. /* sockaddr ? */
  126. char* buf; /* bytes read so far (+0-terminator)*/
  127. char* start; /* where the message starts, after all the empty lines are
  128. skipped*/
  129. char* pos; /* current position in buf */
  130. char* parsed; /* last parsed position */
  131. char* body; /* body position */
  132. unsigned int b_size; /* buffer size-1 (extra space for 0-term)*/
  133. int content_len;
  134. #ifdef READ_HTTP11
  135. int chunk_size;
  136. #endif
  137. unsigned short flags; /* F_TCP_REQ_HAS_CLEN | F_TCP_REQ_COMPLETE */
  138. int bytes_to_go; /* how many bytes we have still to read from the body*/
  139. enum tcp_req_errors error;
  140. enum tcp_req_states state;
  141. };
  142. /* tcp_req flags */
  143. #define F_TCP_REQ_HAS_CLEN 1
  144. #define F_TCP_REQ_COMPLETE 2
  145. #ifdef READ_HTTP11
  146. #define F_TCP_REQ_BCHUNKED 4
  147. #endif
  148. #ifdef READ_MSRP
  149. #define F_TCP_REQ_MSRP_NO 8
  150. #define F_TCP_REQ_MSRP_FRAME 16
  151. #define F_TCP_REQ_MSRP_BODY 32
  152. #endif
  153. #define TCP_REQ_HAS_CLEN(tr) ((tr)->flags & F_TCP_REQ_HAS_CLEN)
  154. #define TCP_REQ_COMPLETE(tr) ((tr)->flags & F_TCP_REQ_COMPLETE)
  155. #ifdef READ_HTTP11
  156. #define TCP_REQ_BCHUNKED(tr) ((tr)->flags & F_TCP_REQ_BCHUNKED)
  157. #endif
  158. struct tcp_connection;
  159. /* tcp port alias structure */
  160. struct tcp_conn_alias{
  161. struct tcp_connection* parent;
  162. struct tcp_conn_alias* next;
  163. struct tcp_conn_alias* prev;
  164. unsigned short port; /* alias port */
  165. unsigned short hash; /* hash index in the address hash */
  166. };
  167. #ifdef TCP_ASYNC
  168. struct tcp_wbuffer{
  169. struct tcp_wbuffer* next;
  170. unsigned int b_size;
  171. char buf[1];
  172. };
  173. struct tcp_wbuffer_queue{
  174. struct tcp_wbuffer* first;
  175. struct tcp_wbuffer* last;
  176. ticks_t wr_timeout; /* write timeout*/
  177. unsigned int queued; /* total size */
  178. unsigned int offset; /* offset in the first wbuffer were data
  179. starts */
  180. unsigned int last_used; /* how much of the last buffer is used */
  181. };
  182. #endif
  183. struct tcp_connection{
  184. int s; /*socket, used by "tcp main" */
  185. int fd; /* used only by "children", don't modify it! private data! */
  186. gen_lock_t write_lock;
  187. int id; /* id (unique!) used to retrieve a specific connection when
  188. reply-ing*/
  189. int reader_pid; /* pid of the active reader process */
  190. struct receive_info rcv; /* src & dst ip, ports, proto a.s.o*/
  191. struct tcp_req req; /* request data */
  192. atomic_t refcnt;
  193. enum sip_protos type; /* PROTO_TCP or a protocol over it, e.g. TLS */
  194. unsigned short flags; /* connection related flags */
  195. snd_flags_t send_flags; /* special send flags */
  196. enum tcp_conn_states state; /* connection state */
  197. void* extra_data; /* extra data associated to the connection, 0 for tcp*/
  198. struct timer_ln timer;
  199. ticks_t timeout;/* connection timeout, after this it will be removed*/
  200. unsigned id_hash; /* hash index in the id_hash */
  201. struct tcp_connection* id_next; /* next, prev in id hash table */
  202. struct tcp_connection* id_prev;
  203. struct tcp_connection* c_next; /* child next prev (use locally) */
  204. struct tcp_connection* c_prev;
  205. struct tcp_conn_alias con_aliases[TCP_CON_MAX_ALIASES];
  206. int aliases; /* aliases number, at least 1 */
  207. #ifdef TCP_ASYNC
  208. struct tcp_wbuffer_queue wbuf_q;
  209. #endif
  210. };
  211. /* helper macros */
  212. #define tcpconn_set_send_flags(c, snd_flags) \
  213. SND_FLAGS_OR(&(c)->send_flags, &(c)->send_flags, &(snd_flags))
  214. #define tcpconn_close_after_send(c) ((c)->send_flags.f & SND_F_CON_CLOSE)
  215. #define TCP_RCV_INFO(c) (&(c)->rcv)
  216. #define TCP_RCV_LADDR(r) (&((r).dst_ip))
  217. #define TCP_RCV_LPORT(r) ((r).dst_port)
  218. #define TCP_RCV_PADDR(r) (&((r).src_ip))
  219. #define TCP_RCV_PPORT(r) ((r).src_port)
  220. #define TCP_RCV_PSU(r) (&(r).src_su)
  221. #define TCP_RCV_SOCK_INFO(r) ((r).bind_address)
  222. #define TCP_RCV_PROTO(r) ((r).proto)
  223. #ifdef USE_COMP
  224. #define TCP_RCV_COMP(r) ((r).comp)
  225. #else
  226. #define TCP_RCV_COMP(r) 0
  227. #endif /* USE_COMP */
  228. #define TCP_LADDR(c) TCP_RCV_LADDR(c->rcv)
  229. #define TCP_LPORT(c) TCP_RCV_LPORT(c->rcv)
  230. #define TCP_PADDR(c) TCP_RCV_PADDR(c->rcv)
  231. #define TCP_PPORT(c) TCP_RCV_PPORT(c->rcv)
  232. #define TCP_PSU(c) TCP_RCV_PSU(c->rcv)
  233. #define TCP_SOCK_INFO(c) TCP_RCV_SOCK_INFO(c->rcv)
  234. #define TCP_PROTO(c) TCP_RCV_PROTO(c->rcv)
  235. #define TCP_COMP(c) TCP_RCV_COMP(c->rcv)
  236. #define tcpconn_ref(c) atomic_inc(&((c)->refcnt))
  237. #define tcpconn_put(c) atomic_dec_and_test(&((c)->refcnt))
  238. #define init_tcp_req( r, rd_buf, rd_buf_size) \
  239. do{ \
  240. memset( (r), 0, sizeof(struct tcp_req)); \
  241. (r)->buf=(rd_buf) ;\
  242. (r)->b_size=(rd_buf_size)-1; /* space for 0 term. */ \
  243. (r)->parsed=(r)->pos=(r)->start=(r)->buf; \
  244. (r)->error=TCP_REQ_OK;\
  245. (r)->state=H_SKIP_EMPTY; \
  246. }while(0)
  247. /* add a tcpconn to a list*/
  248. /* list head, new element, next member, prev member */
  249. #define tcpconn_listadd(head, c, next, prev) \
  250. do{ \
  251. /* add it at the begining of the list*/ \
  252. (c)->next=(head); \
  253. (c)->prev=0; \
  254. if ((head)) (head)->prev=(c); \
  255. (head)=(c); \
  256. } while(0)
  257. /* remove a tcpconn from a list*/
  258. #define tcpconn_listrm(head, c, next, prev) \
  259. do{ \
  260. if ((head)==(c)) (head)=(c)->next; \
  261. if ((c)->next) (c)->next->prev=(c)->prev; \
  262. if ((c)->prev) (c)->prev->next=(c)->next; \
  263. }while(0)
  264. #define TCPCONN_LOCK lock_get(tcpconn_lock);
  265. #define TCPCONN_UNLOCK lock_release(tcpconn_lock);
  266. #define TCP_ALIAS_HASH_SIZE 4096
  267. #define TCP_ID_HASH_SIZE 1024
  268. /* hash (dst_ip, dst_port, local_ip, local_port) */
  269. static inline unsigned tcp_addr_hash( struct ip_addr* ip,
  270. unsigned short port,
  271. struct ip_addr* l_ip,
  272. unsigned short l_port)
  273. {
  274. unsigned h;
  275. if(ip->len==4)
  276. h=(ip->u.addr32[0]^port)^(l_ip->u.addr32[0]^l_port);
  277. else if (ip->len==16)
  278. h= (ip->u.addr32[0]^ip->u.addr32[1]^ip->u.addr32[2]^
  279. ip->u.addr32[3]^port) ^
  280. (l_ip->u.addr32[0]^l_ip->u.addr32[1]^l_ip->u.addr32[2]^
  281. l_ip->u.addr32[3]^l_port);
  282. else{
  283. LM_CRIT("bad len %d for an ip address\n", ip->len);
  284. return 0;
  285. }
  286. /* make sure the first bits are influenced by all 32
  287. * (the first log2(TCP_ALIAS_HASH_SIZE) bits should be a mix of all
  288. * 32)*/
  289. h ^= h>>17;
  290. h ^= h>>7;
  291. return h & (TCP_ALIAS_HASH_SIZE-1);
  292. }
  293. #define tcp_id_hash(id) (id&(TCP_ID_HASH_SIZE-1))
  294. struct tcp_connection* tcpconn_get(int id, struct ip_addr* ip, int port,
  295. union sockaddr_union* local_addr,
  296. ticks_t timeout);
  297. typedef struct tcp_event_info {
  298. int type;
  299. char *buf;
  300. unsigned int len;
  301. struct receive_info *rcv;
  302. struct tcp_connection *con;
  303. } tcp_event_info_t;
  304. typedef struct ws_event_info {
  305. int type;
  306. char *buf;
  307. unsigned int len;
  308. int id;
  309. } ws_event_info_t;
  310. #endif