5b064b1bdebb09e468ef0b05b79c1a4dd3659700
[sip-router] / tcp_conn.h
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  *    info@iptel.org
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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  */
35
36
37
38 #ifndef _tcp_conn_h
39 #define _tcp_conn_h
40
41 #include "ip_addr.h"
42 #include "locking.h"
43 #include "atomic_ops.h"
44 #include "timer_ticks.h"
45
46 #define TCP_CON_MAX_ALIASES 4 /* maximum number of port aliases */
47
48 #define TCP_BUF_SIZE    4096 
49 #define DEFAULT_TCP_CONNECTION_LIFETIME 120 /* in  seconds */
50 #define DEFAULT_TCP_SEND_TIMEOUT 10 /* if a send can't write for more then 10s,
51                                                                            timeout */
52 #define DEFAULT_TCP_CONNECT_TIMEOUT 10 /* if a connect doesn't complete in this
53                                                                                   time, timeout */
54 #define DEFAULT_TCP_MAX_CONNECTIONS 2048 /* maximum connections */
55 #define TCP_CHILD_TIMEOUT 5 /* after 5 seconds, the child "returns" 
56                                                          the connection to the tcp master process */
57 #define TCP_MAIN_SELECT_TIMEOUT 5 /* how often "tcp main" checks for timeout*/
58 #define TCP_CHILD_SELECT_TIMEOUT 2 /* the same as above but for children */
59
60
61 /* tcp connection flags */
62 #define F_CONN_NON_BLOCKING 1
63 #define F_CONN_REMOVED      2 /* no longer  in "main" listen fd list */
64
65
66 enum tcp_req_errors {   TCP_REQ_INIT, TCP_REQ_OK, TCP_READ_ERROR,
67                                                 TCP_REQ_OVERRUN, TCP_REQ_BAD_LEN };
68 enum tcp_req_states {   H_SKIP_EMPTY, H_SKIP, H_LF, H_LFCR,  H_BODY, H_STARTWS,
69                 H_CONT_LEN1, H_CONT_LEN2, H_CONT_LEN3, H_CONT_LEN4, H_CONT_LEN5,
70                 H_CONT_LEN6, H_CONT_LEN7, H_CONT_LEN8, H_CONT_LEN9, H_CONT_LEN10,
71                 H_CONT_LEN11, H_CONT_LEN12, H_CONT_LEN13, H_L_COLON, 
72                 H_CONT_LEN_BODY, H_CONT_LEN_BODY_PARSE,
73                 H_STUN_MSG, H_STUN_READ_BODY, H_STUN_FP, H_STUN_END 
74         };
75
76 enum tcp_conn_states { S_CONN_ERROR=-2, S_CONN_BAD=-1, S_CONN_OK=0, 
77                                                 S_CONN_INIT, S_CONN_EOF, 
78                                                 S_CONN_ACCEPT, S_CONN_CONNECT };
79
80
81 /* fd communication commands */
82 enum conn_cmds { CONN_DESTROY=-3, CONN_ERROR=-2, CONN_EOF=-1, CONN_RELEASE, 
83                                         CONN_GET_FD, CONN_NEW };
84 /* CONN_RELEASE, EOF, ERROR, DESTROY can be used by "reader" processes
85  * CONN_GET_FD, NEW, ERROR only by writers */
86
87 struct tcp_req{
88         struct tcp_req* next;
89         /* sockaddr ? */
90         char buf[TCP_BUF_SIZE+1]; /* bytes read so far (+0-terminator)*/
91         char* start; /* where the message starts, after all the empty lines are
92                                         skipped*/
93         char* pos; /* current position in buf */
94         char* parsed; /* last parsed position */
95         char* body; /* body position */
96         int content_len;
97         int has_content_len; /* 1 if content_length was parsed ok*/
98         int complete; /* 1 if one req has been fully read, 0 otherwise*/
99         int bytes_to_go; /* how many bytes we have still to read from the body*/
100         enum tcp_req_errors error;
101         enum tcp_req_states state;
102 };
103
104
105
106 struct tcp_connection;
107
108 /* tcp port alias structure */
109 struct tcp_conn_alias{
110         struct tcp_connection* parent;
111         struct tcp_conn_alias* next;
112         struct tcp_conn_alias* prev;
113         unsigned short port; /* alias port */
114         unsigned short hash; /* hash index in the address hash */
115 };
116
117
118
119 struct tcp_connection{
120         int s; /*socket, used by "tcp main" */
121         int fd; /* used only by "children", don't modify it! private data! */
122         gen_lock_t write_lock;
123         int id; /* id (unique!) used to retrieve a specific connection when
124                    reply-ing*/
125         struct receive_info rcv; /* src & dst ip, ports, proto a.s.o*/
126         struct tcp_req req; /* request data */
127         atomic_t refcnt;
128         enum sip_protos type; /* PROTO_TCP or a protocol over it, e.g. TLS */
129         int flags; /* connection related flags */
130         enum tcp_conn_states state; /* connection state */
131         void* extra_data; /* extra data associated to the connection, 0 for tcp*/
132         unsigned int timeout;/* connection timeout, after this it will be removed*/
133         unsigned id_hash; /* hash index in the id_hash */
134         struct tcp_connection* id_next; /* next, prev in id hash table */
135         struct tcp_connection* id_prev;
136         struct tcp_connection* c_next; /* child next prev (use locally) */
137         struct tcp_connection* c_prev;
138         struct tcp_conn_alias con_aliases[TCP_CON_MAX_ALIASES];
139         int aliases; /* aliases number, at least 1 */
140 };
141
142
143
144
145
146 #define tcpconn_ref(c) atomic_inc(&((c)->refcnt))
147 #define tcpconn_put(c) atomic_dec(&((c)->refcnt))
148
149
150 #define init_tcp_req( r) \
151         do{ \
152                 memset( (r), 0, sizeof(struct tcp_req)); \
153                 (r)->parsed=(r)->pos=(r)->start=(r)->buf; \
154                 (r)->error=TCP_REQ_OK;\
155                 (r)->state=H_SKIP_EMPTY; \
156         }while(0)
157
158
159 /* add a tcpconn to a list*/
160 /* list head, new element, next member, prev member */
161 #define tcpconn_listadd(head, c, next, prev) \
162         do{ \
163                 /* add it at the begining of the list*/ \
164                 (c)->next=(head); \
165                 (c)->prev=0; \
166                 if ((head)) (head)->prev=(c); \
167                 (head)=(c); \
168         } while(0)
169
170
171 /* remove a tcpconn from a list*/
172 #define tcpconn_listrm(head, c, next, prev) \
173         do{ \
174                 if ((head)==(c)) (head)=(c)->next; \
175                 if ((c)->next) (c)->next->prev=(c)->prev; \
176                 if ((c)->prev) (c)->prev->next=(c)->next; \
177         }while(0)
178
179
180 #define TCPCONN_LOCK lock_get(tcpconn_lock);
181 #define TCPCONN_UNLOCK lock_release(tcpconn_lock);
182
183 #define TCP_ALIAS_HASH_SIZE 1024
184 #define TCP_ID_HASH_SIZE 1024
185
186 static inline unsigned tcp_addr_hash(struct ip_addr* ip, unsigned short port)
187 {
188         if(ip->len==4) return (ip->u.addr32[0]^port)&(TCP_ALIAS_HASH_SIZE-1);
189         else if (ip->len==16) 
190                         return (ip->u.addr32[0]^ip->u.addr32[1]^ip->u.addr32[2]^
191                                         ip->u.addr32[3]^port) & (TCP_ALIAS_HASH_SIZE-1);
192         else{
193                 LOG(L_CRIT, "tcp_addr_hash: BUG: bad len %d for an ip address\n",
194                                 ip->len);
195                 return 0;
196         }
197 }
198
199 #define tcp_id_hash(id) (id&(TCP_ID_HASH_SIZE-1))
200
201 struct tcp_connection* tcpconn_get(int id, struct ip_addr* ip, int port,
202                                                                         ticks_t timeout);
203
204 #endif
205
206