- more tcp stuff (uses locking.h, hashtables, mostly untested)
[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
29
30 #ifndef _tcp_conn_h
31 #define _tcp_conn_h
32
33 #include "ip_addr.h"
34
35
36 #define TCP_BUF_SIZE 65535
37 #define TCP_CON_TIMEOUT 60 /* in  seconds */
38 #define TCP_CHILD_TIMEOUT 5 /* after 5 seconds, the child "returns" 
39                                                          the connection to the tcp master process */
40 #define TCP_MAIN_SELECT_TIMEOUT 5 /* how often "tcp main" checks for timeout*/
41 #define TCP_CHILD_SELECT_TIMEOUT 2 /* the same as above but for children */
42
43
44 enum tcp_req_errors {   TCP_REQ_INIT, TCP_REQ_OK, TCP_READ_ERROR,
45                                                 TCP_REQ_OVERRUN, TCP_REQ_BAD_LEN };
46 enum tcp_req_states {   H_SKIP_EMPTY, H_SKIP, H_LF, H_LFCR,  H_BODY, H_STARTWS,
47                 H_CONT_LEN1, H_CONT_LEN2, H_CONT_LEN3, H_CONT_LEN4, H_CONT_LEN5,
48                 H_CONT_LEN6, H_CONT_LEN7, H_CONT_LEN8, H_CONT_LEN9, H_CONT_LEN10,
49                 H_CONT_LEN11, H_CONT_LEN12, H_CONT_LEN13, H_L_COLON, 
50                 H_CONT_LEN_BODY, H_CONT_LEN_BODY_PARSE 
51         };
52
53 /* fd communication commands */
54 enum conn_cmds { CONN_DESTROY=-3, CONN_ERROR=-2, CONN_EOF=-1, CONN_RELEASE, 
55                                         CONN_GET_FD, CONN_NEW };
56
57 struct tcp_req{
58         struct tcp_req* next;
59         /* sockaddr ? */
60         char buf[TCP_BUF_SIZE]; /* bytes read so far*/
61         char* start; /* where the message starts, after alll the empty lines are
62                                         skipped*/
63         char* pos; /* current position in buf */
64         char* parsed; /* last parsed position */
65         char* body; /* body position */
66         int content_len;
67         int has_content_len; /* 1 if content_length was parsed ok*/
68         int complete; /* 1 if one req has been fully read, 0 otherwise*/
69         int bytes_to_go; /* how many bytes we have still to read from the body*/
70         enum tcp_req_errors error;
71         enum tcp_req_states state;
72 };
73
74
75
76
77 struct tcp_connection{
78         int s; /*socket, used by "tcp main" */
79         int fd; /* used only by "children" */
80         int id; /* id (unique!) used to retrieve a specific connection when
81                    reply-ing*/
82         struct receive_info rcv; /* src & dst ip, ports, proto a.s.o*/
83 #if 0
84         struct ip_addr ip; /* peer ip */
85         int port; /* peer port */
86         int sock_idx; /* receiving socket index in the tcp_info array */
87         union sockaddr_union su;
88 #endif
89         struct tcp_req req; /* request data */
90         int refcnt;
91         int timeout; /* connection timeout, after this it will be removed*/
92         unsigned addr_hash; /* hash indexes in thge 2 tables */
93         unsigned id_hash;
94         struct tcp_connection* next; /* next, prev in hash table, used by "main" */
95         struct tcp_connection* prev;
96         struct tcp_connection* id_next; /* next, prev in id hash table */
97         struct tcp_connection* id_prev;
98         struct tcp_connection* c_next; /* child next prev (use locally) */
99         struct tcp_connection* c_prev;
100 };
101
102
103
104
105 #define init_tcp_req( r) \
106         do{ \
107                 memset( (r), 0, sizeof(struct tcp_req)); \
108                 (r)->parsed=(r)->pos=(r)->start=(r)->buf; \
109                 (r)->error=TCP_REQ_OK;\
110                 (r)->state=H_SKIP_EMPTY; \
111         }while(0)
112
113
114 /* add a tcpconn to a list*/
115 /* list head, new element, next member, prev member */
116 #define tcpconn_listadd(head, c, next, prev) \
117         do{ \
118                 /* add it at the begining of the list*/ \
119                 (c)->next=(head); \
120                 (c)->prev=0; \
121                 if ((head)) (head)->prev=(c); \
122                 (head)=(c); \
123         } while(0)
124
125
126 /* remove a tcpconn from a list*/
127 #define tcpconn_listrm(head, c, next, prev) \
128         do{ \
129                 if ((head)==(c)) (head)=(c)->next; \
130                 if ((c)->next) (c)->next->prev=(c)->prev; \
131                 if ((c)->prev) (c)->prev->next=(c)->next; \
132         }while(0)
133
134
135 #define TCPCONN_LOCK lock_get(tcpconn_lock);
136 #define TCPCONN_UNLOCK lock_release(tcpconn_lock);
137
138 #define TCP_ADDR_HASH_SIZE 1024
139 #define TCP_ID_HASH_SIZE 1024
140
141 static inline unsigned tcp_addr_hash(struct ip_addr* ip, unsigned short port)
142 {
143         if(ip->len==4) return (ip->u.addr32[0]^port)&(TCP_ADDR_HASH_SIZE-1);
144         else if (ip->len==16) 
145                         return (ip->u.addr32[0]^ip->u.addr32[1]^ip->u.addr32[2]^
146                                         ip->u.addr32[3]^port) & (TCP_ADDR_HASH_SIZE-1);
147         else{
148                 LOG(L_CRIT, "tcp_addr_hash: BUG: bad len %d for an ip address\n",
149                                 ip->len);
150                 return 0;
151         }
152 }
153
154 #define tcp_id_hash(id) (id&(TCP_ID_HASH_SIZE-1))
155
156
157 #endif
158
159