00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef _tcp_conn_h
00038 #define _tcp_conn_h
00039
00040 #include "ip_addr.h"
00041 #include "locking.h"
00042
00043
00044 #define TCP_CON_MAX_ALIASES 4
00045
00046 #define TCP_BUF_SIZE 65535
00047 #define DEFAULT_TCP_CONNECTION_LIFETIME 120
00048 #define DEFAULT_TCP_SEND_TIMEOUT 10
00049 #define DEFAULT_TCP_CONNECT_TIMEOUT 10
00050 #define DEFAULT_TCP_MAX_CONNECTIONS 2048
00051 #define TCP_CHILD_TIMEOUT 5
00052
00053 #define TCP_MAIN_SELECT_TIMEOUT 5
00054 #define TCP_CHILD_SELECT_TIMEOUT 2
00055
00056
00057
00058 #define F_CONN_NON_BLOCKING 1
00059 #define F_CONN_REMOVED 2
00060
00061
00062 enum tcp_req_errors { TCP_REQ_INIT, TCP_REQ_OK, TCP_READ_ERROR,
00063 TCP_REQ_OVERRUN, TCP_REQ_BAD_LEN };
00064 enum tcp_req_states { H_SKIP_EMPTY, H_SKIP, H_LF, H_LFCR, H_BODY, H_STARTWS,
00065 H_CONT_LEN1, H_CONT_LEN2, H_CONT_LEN3, H_CONT_LEN4, H_CONT_LEN5,
00066 H_CONT_LEN6, H_CONT_LEN7, H_CONT_LEN8, H_CONT_LEN9, H_CONT_LEN10,
00067 H_CONT_LEN11, H_CONT_LEN12, H_CONT_LEN13, H_L_COLON,
00068 H_CONT_LEN_BODY, H_CONT_LEN_BODY_PARSE , H_PING_CRLFCRLF,
00069 H_SKIP_EMPTY_CR_FOUND, H_SKIP_EMPTY_CRLF_FOUND, H_SKIP_EMPTY_CRLFCR_FOUND
00070 };
00071
00072 enum tcp_conn_states { S_CONN_ERROR=-2, S_CONN_BAD=-1, S_CONN_OK=0,
00073 S_CONN_INIT, S_CONN_EOF, S_CONN_ACCEPT, S_CONN_CONNECT };
00074
00075
00076
00077 enum conn_cmds { CONN_DESTROY=-3, CONN_ERROR=-2, CONN_EOF=-1, CONN_RELEASE,
00078 CONN_GET_FD, CONN_NEW };
00079
00080
00081
00082 struct tcp_req{
00083 struct tcp_req* next;
00084
00085 char buf[TCP_BUF_SIZE+1];
00086 char* start;
00087 char* pos;
00088 char* parsed;
00089 char* body;
00090 unsigned int content_len;
00091 unsigned short has_content_len;
00092 unsigned short complete;
00093 unsigned int bytes_to_go;
00094 enum tcp_req_errors error;
00095 enum tcp_req_states state;
00096 };
00097
00098
00099
00100 struct tcp_connection;
00101
00102
00103 struct tcp_conn_alias{
00104 struct tcp_connection* parent;
00105 struct tcp_conn_alias* next;
00106 struct tcp_conn_alias* prev;
00107 unsigned short port;
00108 unsigned short hash;
00109 };
00110
00111
00112
00113
00114 struct tcp_connection{
00115 int s;
00116 int fd;
00117 gen_lock_t write_lock;
00118 int id;
00119 struct receive_info rcv;
00120 struct tcp_req req;
00121 volatile int refcnt;
00122 enum sip_protos type;
00123 int flags;
00124 enum tcp_conn_states state;
00125 void* extra_data;
00126 unsigned int timeout;
00127 unsigned int lifetime;
00128 unsigned id_hash;
00129 struct tcp_connection* id_next;
00130 struct tcp_connection* id_prev;
00131 struct tcp_connection* c_next;
00132 struct tcp_connection* c_prev;
00133 struct tcp_conn_alias con_aliases[TCP_CON_MAX_ALIASES];
00134 int aliases;
00135 };
00136
00137
00138
00139 #define init_tcp_req( r) \
00140 do{ \
00141 memset( (r), 0, sizeof(struct tcp_req)); \
00142 (r)->parsed=(r)->pos=(r)->start=(r)->buf; \
00143 (r)->error=TCP_REQ_OK;\
00144 (r)->state=H_SKIP_EMPTY; \
00145 }while(0)
00146
00147
00148
00149
00150 #define tcpconn_listadd(head, c, next, prev) \
00151 do{ \
00152 \
00153 (c)->next=(head); \
00154 (c)->prev=0; \
00155 if ((head)) (head)->prev=(c); \
00156 (head)=(c); \
00157 } while(0)
00158
00159
00160
00161 #define tcpconn_listrm(head, c, next, prev) \
00162 do{ \
00163 if ((head)==(c)) (head)=(c)->next; \
00164 if ((c)->next) (c)->next->prev=(c)->prev; \
00165 if ((c)->prev) (c)->prev->next=(c)->next; \
00166 }while(0)
00167
00168
00169 #define TCPCONN_LOCK lock_get(tcpconn_lock);
00170 #define TCPCONN_UNLOCK lock_release(tcpconn_lock);
00171
00172 #define TCP_ALIAS_HASH_SIZE 1024
00173 #define TCP_ID_HASH_SIZE 1024
00174
00175 static inline unsigned tcp_addr_hash(struct ip_addr* ip, unsigned short port)
00176 {
00177 if(ip->len==4) return (ip->u.addr32[0]^port)&(TCP_ALIAS_HASH_SIZE-1);
00178 else if (ip->len==16)
00179 return (ip->u.addr32[0]^ip->u.addr32[1]^ip->u.addr32[2]^
00180 ip->u.addr32[3]^port) & (TCP_ALIAS_HASH_SIZE-1);
00181 else{
00182 LM_CRIT("bad len %d for an ip address\n", ip->len);
00183 return 0;
00184 }
00185 }
00186
00187 #define tcp_id_hash(id) (id&(TCP_ID_HASH_SIZE-1))
00188
00189
00190 #endif
00191