... | ... |
@@ -16,6 +16,7 @@ |
16 | 16 |
#include "ut.h" |
17 | 17 |
#include "sr_module.h" |
18 | 18 |
#include "mem/mem.h" |
19 |
+#include "globals.h" |
|
19 | 20 |
|
20 | 21 |
#include <sys/types.h> |
21 | 22 |
#include <sys/socket.h> |
... | ... |
@@ -48,6 +49,13 @@ int do_action(struct action* a, struct sip_msg* msg) |
48 | 49 |
struct sip_uri uri; |
49 | 50 |
unsigned short port; |
50 | 51 |
|
52 |
+ /* reset the value of error to E_UNSPEC so avoid unknowledgable |
|
53 |
+ functions to return with errror (status<0) and not setting it |
|
54 |
+ leaving there previous error; cache the previous value though |
|
55 |
+ for functions which want to process it */ |
|
56 |
+ prev_ser_error=ser_error; |
|
57 |
+ ser_error=E_UNSPEC; |
|
58 |
+ |
|
51 | 59 |
ret=E_BUG; |
52 | 60 |
switch (a->type){ |
53 | 61 |
case DROP_T: |
... | ... |
@@ -63,10 +71,10 @@ int do_action(struct action* a, struct sip_msg* msg) |
63 | 71 |
tmp=msg->first_line.u.request.uri.s; |
64 | 72 |
len=msg->first_line.u.request.uri.len; |
65 | 73 |
} |
66 |
- if (parse_uri(tmp, len, &uri)<0){ |
|
74 |
+ ret=parse_uri(tmp, len, &uri ); |
|
75 |
+ if (ret<0) { |
|
67 | 76 |
LOG(L_ERR, "ERROR: do_action: forward: bad_uri <%s>," |
68 | 77 |
" dropping packet\n",tmp); |
69 |
- ret=E_UNSPEC; |
|
70 | 78 |
break; |
71 | 79 |
} |
72 | 80 |
switch (a->p2_type){ |
... | ... |
@@ -80,7 +88,7 @@ int do_action(struct action* a, struct sip_msg* msg) |
80 | 88 |
LOG(L_ERR, "ERROR: do_action: " |
81 | 89 |
"forward: bad port in " |
82 | 90 |
"uri: <%s>\n", uri.port.s); |
83 |
- ret=E_UNSPEC; |
|
91 |
+ ret=E_BAD_URI; |
|
84 | 92 |
goto error_fwd_uri; |
85 | 93 |
} |
86 | 94 |
}else port=SIP_PORT; |
... | ... |
@@ -5,6 +5,8 @@ |
5 | 5 |
#include "data_lump.h" |
6 | 6 |
#include "dprint.h" |
7 | 7 |
#include "mem/mem.h" |
8 |
+#include "globals.h" |
|
9 |
+#include "error.h" |
|
8 | 10 |
|
9 | 11 |
#include <stdlib.h> |
10 | 12 |
#include <string.h> |
... | ... |
@@ -14,7 +16,6 @@ |
14 | 16 |
#endif |
15 | 17 |
|
16 | 18 |
|
17 |
- |
|
18 | 19 |
/* adds a header to the end |
19 | 20 |
* returns pointer on success, 0 on error */ |
20 | 21 |
struct lump* append_new_lump(struct lump** list, char* new_hdr, |
... | ... |
@@ -75,6 +76,7 @@ struct lump* insert_new_lump_after( struct lump* after, char* new_hdr, |
75 | 76 |
|
76 | 77 |
tmp=pkg_malloc(sizeof(struct lump)); |
77 | 78 |
if (tmp==0){ |
79 |
+ ser_error=E_OUT_OF_MEM; |
|
78 | 80 |
LOG(L_ERR, "ERROR: insert_new_lump_after: out of memory\n"); |
79 | 81 |
return 0; |
80 | 82 |
} |
... | ... |
@@ -99,6 +101,7 @@ struct lump* insert_new_lump_before( struct lump* before, char* new_hdr, |
99 | 101 |
|
100 | 102 |
tmp=pkg_malloc(sizeof(struct lump)); |
101 | 103 |
if (tmp==0){ |
104 |
+ ser_error=E_OUT_OF_MEM; |
|
102 | 105 |
LOG(L_ERR,"ERROR: insert_new_lump_before: out of memory\n"); |
103 | 106 |
return 0; |
104 | 107 |
} |
... | ... |
@@ -152,6 +155,7 @@ struct lump* anchor_lump(struct lump** list, int offset, int len, int type) |
152 | 155 |
|
153 | 156 |
tmp=pkg_malloc(sizeof(struct lump)); |
154 | 157 |
if (tmp==0){ |
158 |
+ ser_error=E_OUT_OF_MEM; |
|
155 | 159 |
LOG(L_ERR, "ERROR: insert_new_lump_before: out of memory\n"); |
156 | 160 |
return 0; |
157 | 161 |
} |
158 | 162 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,52 @@ |
1 |
+/* |
|
2 |
+ * $Id$ |
|
3 |
+ * |
|
4 |
+ */ |
|
5 |
+ |
|
6 |
+#include "error.h" |
|
7 |
+ |
|
8 |
+/* current function's error; */ |
|
9 |
+int ser_error=-1; |
|
10 |
+/* previous error */ |
|
11 |
+int prev_ser_error=-1; |
|
12 |
+ |
|
13 |
+int err2reason_phrase( |
|
14 |
+ int ser_error, /* current itnernal ser error */ |
|
15 |
+ int *sip_error, /* the sip error code to which ser |
|
16 |
+ ser error will be turned */ |
|
17 |
+ char *phrase, /* resulting error text */ |
|
18 |
+ int etl, /* error text buffer length */ |
|
19 |
+ char *signature ) /* extra text to be appended */ |
|
20 |
+{ |
|
21 |
+ |
|
22 |
+ char *error_txt; |
|
23 |
+ |
|
24 |
+ switch( ser_error ) { |
|
25 |
+ case E_OUT_OF_MEM: |
|
26 |
+ error_txt="Excuse me I ran out of memory"; |
|
27 |
+ *sip_error=500; |
|
28 |
+ break; |
|
29 |
+ case E_SEND: |
|
30 |
+ error_txt="Unfortunately error on sending to next hop occured"; |
|
31 |
+ *sip_error=-ser_error; |
|
32 |
+ break; |
|
33 |
+ case E_BAD_ADDRESS: |
|
34 |
+ error_txt="Unresolveable destination"; |
|
35 |
+ *sip_error=-ser_error; |
|
36 |
+ break; |
|
37 |
+ case E_BAD_REQ: |
|
38 |
+ error_txt="Bad Request"; |
|
39 |
+ *sip_error=-ser_error; |
|
40 |
+ break; |
|
41 |
+ case E_BAD_URI: |
|
42 |
+ error_txt="Regretfuly, we were not able to process the URI"; |
|
43 |
+ *sip_error=-ser_error; |
|
44 |
+ break; |
|
45 |
+ default: |
|
46 |
+ error_txt="I'm terribly sorry, server error occured"; |
|
47 |
+ *sip_error=500; |
|
48 |
+ break; |
|
49 |
+ } |
|
50 |
+ return snprintf( phrase, etl, "%s (%d/%s)", error_txt, |
|
51 |
+ -ser_error, signature ); |
|
52 |
+} |
... | ... |
@@ -8,9 +8,27 @@ |
8 | 8 |
#define E_UNSPEC -1 |
9 | 9 |
#define E_OUT_OF_MEM -2 |
10 | 10 |
#define E_BAD_RE -3 |
11 |
-#define E_BAD_ADDRESS -4 |
|
11 |
+/* #define E_BAD_ADDRESS -4 */ |
|
12 | 12 |
#define E_BUG -5 |
13 | 13 |
#define E_CFG -6 |
14 |
+#define E_NO_SOCKET -7 |
|
15 |
+ |
|
16 |
+#define E_SEND -477 |
|
17 |
+/* unresolveable next-hop address */ |
|
18 |
+#define E_BAD_ADDRESS -478 |
|
19 |
+/* unparseable URI */ |
|
20 |
+#define E_BAD_URI -479 |
|
21 |
+/* misformated request */ |
|
22 |
+#define E_BAD_REQ -400 |
|
23 |
+ |
|
24 |
+#define MAX_REASON_LEN 128 |
|
25 |
+ |
|
26 |
+/* processing status of the last command */ |
|
27 |
+extern int ser_error; |
|
28 |
+extern int prev_ser_error; |
|
29 |
+ |
|
30 |
+int err2reason_phrase( int ser_error, int *sip_error, |
|
31 |
+ char *phrase, int etl, char *signature ); |
|
14 | 32 |
|
15 | 33 |
|
16 | 34 |
#endif |
... | ... |
@@ -73,6 +73,7 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p) |
73 | 73 |
|
74 | 74 |
to=(union sockaddr_union*)malloc(sizeof(union sockaddr_union)); |
75 | 75 |
if (to==0){ |
76 |
+ ser_error=E_OUT_OF_MEM; |
|
76 | 77 |
LOG(L_ERR, "ERROR: forward_request: out of memory\n"); |
77 | 78 |
goto error; |
78 | 79 |
} |
... | ... |
@@ -96,6 +97,7 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p) |
96 | 97 |
if (send_sock==0){ |
97 | 98 |
LOG(L_ERR, "forward_req: ERROR: cannot forward to af %d " |
98 | 99 |
"no coresponding listening socket\n", to->s.sa_family); |
100 |
+ ser_error=E_NO_SOCKET; |
|
99 | 101 |
goto error; |
100 | 102 |
} |
101 | 103 |
|
... | ... |
@@ -110,6 +112,7 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p) |
110 | 112 |
|
111 | 113 |
if (udp_send( send_sock, buf, len, to, |
112 | 114 |
sizeof(union sockaddr_union))==-1){ |
115 |
+ ser_error=E_SEND; |
|
113 | 116 |
p->errors++; |
114 | 117 |
p->ok=0; |
115 | 118 |
STATS_TX_DROPS; |
... | ... |
@@ -9,6 +9,8 @@ |
9 | 9 |
#include "../../md5utils.h" |
10 | 10 |
/* bogdan test */ |
11 | 11 |
#include "../../ut.h" |
12 |
+#include "../../globals.h" |
|
13 |
+#include "../../error.h" |
|
12 | 14 |
|
13 | 15 |
|
14 | 16 |
|
... | ... |
@@ -75,8 +77,10 @@ struct cell* build_cell( struct sip_msg* p_msg ) |
75 | 77 |
|
76 | 78 |
/* allocs a new cell */ |
77 | 79 |
new_cell = (struct cell*)sh_malloc( sizeof( struct cell ) ); |
78 |
- if ( !new_cell ) |
|
80 |
+ if ( !new_cell ) { |
|
81 |
+ ser_error=E_OUT_OF_MEM; |
|
79 | 82 |
return NULL; |
83 |
+ } |
|
80 | 84 |
|
81 | 85 |
/* filling with 0 */ |
82 | 86 |
memset( new_cell, 0, sizeof( struct cell ) ); |
... | ... |
@@ -54,7 +54,11 @@ typedef struct retr_buf |
54 | 54 |
char *cancel; |
55 | 55 |
int cancel_len; |
56 | 56 |
|
57 |
- struct sockaddr_in to; |
|
57 |
+ /* v6 changes; -jiri |
|
58 |
+ struct sockaddr_in to; */ |
|
59 |
+ union sockaddr_union to; |
|
60 |
+ struct socket_info* send_sock; |
|
61 |
+ |
|
58 | 62 |
size_t tolen; |
59 | 63 |
|
60 | 64 |
/* a message can be linked just to retransmission and FR list */ |
... | ... |
@@ -144,7 +148,9 @@ typedef struct cell |
144 | 148 |
|
145 | 149 |
/* this is where destination is stored for picked branch; |
146 | 150 |
good if a need to forward ACK later on */ |
147 |
- struct sockaddr_in ack_to; |
|
151 |
+ /* v6 changes; -jiri |
|
152 |
+ struct sockaddr_in ack_to; */ |
|
153 |
+ union sockaddr_union ack_to; |
|
148 | 154 |
#ifndef USE_SYNONIM |
149 | 155 |
/* MD5checksum */ |
150 | 156 |
char md5[MD5_LEN]; |
151 | 157 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,95 @@ |
1 |
+/* |
|
2 |
+ * $Id$ |
|
3 |
+ * |
|
4 |
+ * forking requests |
|
5 |
+ */ |
|
6 |
+ |
|
7 |
+#include "../../dprint.h" |
|
8 |
+#include "../../config.h" |
|
9 |
+#include "../../parser/parser_f.h" |
|
10 |
+#include "../../ut.h" |
|
11 |
+#include "hash_func.h" |
|
12 |
+#include "t_funcs.h" |
|
13 |
+#include "t_fork.h" |
|
14 |
+ |
|
15 |
+ |
|
16 |
+ |
|
17 |
+unsigned int nr_forks; |
|
18 |
+struct fork t_forks[ NR_OF_CLIENTS ]; |
|
19 |
+ |
|
20 |
+ |
|
21 |
+int t_add_fork( union sockaddr_union to, char* uri_s, |
|
22 |
+ unsigned int uri_len, enum fork_type type, |
|
23 |
+ unsigned char free_flag) |
|
24 |
+{ |
|
25 |
+ unsigned int pos=0; |
|
26 |
+ char *foo=0; |
|
27 |
+ |
|
28 |
+ switch (type) |
|
29 |
+ { |
|
30 |
+ case DEFAULT: |
|
31 |
+ if (nr_forks+1>=MAX_FORK) |
|
32 |
+ { |
|
33 |
+ LOG(L_ERR,"ERROR:t_add_fork: trying to add new fork ->" |
|
34 |
+ " MAX_FORK exceded\n"); |
|
35 |
+ return -1; |
|
36 |
+ } |
|
37 |
+ pos = ++nr_forks; |
|
38 |
+ break; |
|
39 |
+ case NO_RESPONSE: |
|
40 |
+ /* v6; -Jiri |
|
41 |
+ if (t_forks[NO_RPL_BRANCH].ip) |
|
42 |
+ */ |
|
43 |
+ if (!t_forks[NO_RPL_BRANCH].inactive) |
|
44 |
+ LOG(L_WARN,"WARNING:t_add_fork: trying to add NO_RPL fork ->" |
|
45 |
+ " it was set before -> overriding\n"); |
|
46 |
+ if (uri_s && uri_len) |
|
47 |
+ { |
|
48 |
+ foo = (char*)shm_malloc(uri_len); |
|
49 |
+ if (!foo) |
|
50 |
+ { |
|
51 |
+ LOG(L_ERR,"ERROR:t_add_fork: cannot get free memory\n"); |
|
52 |
+ return -1; |
|
53 |
+ } |
|
54 |
+ memcpy(foo,uri_s,uri_len); |
|
55 |
+ } |
|
56 |
+ if (free_flag && uri_s) |
|
57 |
+ pkg_free(uri_s); |
|
58 |
+ uri_s = foo; |
|
59 |
+ free_flag = 0; |
|
60 |
+ pos = NO_RPL_BRANCH; |
|
61 |
+ } |
|
62 |
+ /* -v6 |
|
63 |
+ t_forks[pos].ip = ip; |
|
64 |
+ t_forks[pos].port = port; |
|
65 |
+ */ |
|
66 |
+ t_forks[pos].to=to; |
|
67 |
+ |
|
68 |
+ if (uri_s && uri_len) |
|
69 |
+ { |
|
70 |
+ t_forks[pos].free_flag = free_flag; |
|
71 |
+ t_forks[pos].uri.len = uri_len; |
|
72 |
+ t_forks[pos].uri.s = uri_s; |
|
73 |
+ } |
|
74 |
+ |
|
75 |
+ return 1; |
|
76 |
+} |
|
77 |
+ |
|
78 |
+ |
|
79 |
+ |
|
80 |
+ |
|
81 |
+int t_clear_forks( ) |
|
82 |
+{ |
|
83 |
+ int i; |
|
84 |
+ |
|
85 |
+ DBG("DEBUG: t_clear_forks: clearing tabel...\n"); |
|
86 |
+ for(i=1;i<nr_forks;i++) |
|
87 |
+ if (t_forks[i].free_flag && t_forks[i].uri.s) |
|
88 |
+ pkg_free(t_forks[i].uri.s); |
|
89 |
+ memset( t_forks, 0, sizeof(t_forks)); |
|
90 |
+ nr_forks = 0; |
|
91 |
+ return 1; |
|
92 |
+} |
|
93 |
+ |
|
94 |
+ |
|
95 |
+ |
0 | 96 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,30 @@ |
1 |
+/* |
|
2 |
+ * $Id$ |
|
3 |
+ */ |
|
4 |
+ |
|
5 |
+#ifndef _T_FORKS_H |
|
6 |
+#define _T_FORKS_H |
|
7 |
+ |
|
8 |
+#include "../../ip_addr.h" |
|
9 |
+#include "../../str.h" |
|
10 |
+ |
|
11 |
+ |
|
12 |
+struct fork |
|
13 |
+{ |
|
14 |
+ union sockaddr_union to; |
|
15 |
+ char inactive; |
|
16 |
+ unsigned char free_flag; |
|
17 |
+ str uri; |
|
18 |
+ |
|
19 |
+}; |
|
20 |
+ |
|
21 |
+extern struct fork t_forks[ NR_OF_CLIENTS ]; |
|
22 |
+extern unsigned int nr_forks; |
|
23 |
+ |
|
24 |
+int t_add_fork( union sockaddr_union to, char* uri_s, |
|
25 |
+ unsigned int uri_len, enum fork_type type, |
|
26 |
+ unsigned char free_flag); |
|
27 |
+int t_clear_forks(); |
|
28 |
+ |
|
29 |
+ |
|
30 |
+#endif |
... | ... |
@@ -1,38 +1,21 @@ |
1 | 1 |
/* |
2 | 2 |
* $Id$ |
3 | 3 |
* |
4 |
+ * transaction maintenance functions |
|
4 | 5 |
*/ |
5 | 6 |
|
6 |
-#include "hash_func.h" |
|
7 |
-#include "t_funcs.h" |
|
8 | 7 |
#include "../../dprint.h" |
9 | 8 |
#include "../../config.h" |
10 | 9 |
#include "../../parser/parser_f.h" |
11 | 10 |
#include "../../ut.h" |
12 |
-//#include "../../timer.h" |
|
13 |
- |
|
14 |
- |
|
15 |
- |
|
16 |
-#define append_mem_block(_d,_s,_len) \ |
|
17 |
- do{\ |
|
18 |
- memcpy((_d),(_s),(_len));\ |
|
19 |
- (_d) += (_len);\ |
|
20 |
- }while(0); |
|
21 |
-#define req_line(_msg) \ |
|
22 |
- ((_msg)->first_line.u.request) |
|
23 |
- |
|
11 |
+#include "hash_func.h" |
|
12 |
+#include "t_funcs.h" |
|
13 |
+#include "t_fork.h" |
|
24 | 14 |
|
25 | 15 |
|
26 | 16 |
struct cell *T; |
27 | 17 |
unsigned int global_msg_id; |
28 | 18 |
struct s_table* hash_table; |
29 |
-unsigned int nr_forks; |
|
30 |
-struct fork t_forks[ NR_OF_CLIENTS ]; |
|
31 |
- |
|
32 |
- |
|
33 |
- |
|
34 |
-void timer_routine(unsigned int, void*); |
|
35 |
- |
|
36 | 19 |
|
37 | 20 |
|
38 | 21 |
int tm_startup() |
... | ... |
@@ -193,85 +176,6 @@ int t_update_timers_after_sending_reply( struct retr_buf *rb ) |
193 | 176 |
|
194 | 177 |
|
195 | 178 |
|
196 |
-/* Checks if the new reply (with new_code status) should be sent or not |
|
197 |
- * based on the current |
|
198 |
- * transactin status. |
|
199 |
- * Returns - branch number (0,1,...) which should be relayed |
|
200 |
- * -1 if nothing to be relayed |
|
201 |
- */ |
|
202 |
-int t_should_relay_response( struct cell *Trans , int new_code, |
|
203 |
- int branch , int *should_store ) |
|
204 |
-{ |
|
205 |
- //int T_code; |
|
206 |
- int b, lowest_b, lowest_s; |
|
207 |
- |
|
208 |
- //if (Trans->uas.request->REQ_METHOD==METHOD_INVITE) |
|
209 |
- // T_code = Trans->uac[branch].status; |
|
210 |
- //else |
|
211 |
- //T_code = Trans->uas.status; |
|
212 |
- |
|
213 |
- /* note: this code never lets replies to CANCEL go through; |
|
214 |
- we generate always a local 200 for CANCEL; 200s are |
|
215 |
- not relayed because it's not an INVITE transaction; |
|
216 |
- >= 300 are not relayed because 200 was already sent |
|
217 |
- out |
|
218 |
- */ |
|
219 |
- DBG("->>>>>>>>> T_code=%d, new_code=%d\n",Trans->uas.status,new_code); |
|
220 |
- /* if final response sent out, allow only INVITE 2xx */ |
|
221 |
- if ( Trans->uas.status >= 200 ) { |
|
222 |
- if (new_code>=200 && new_code < 300 && |
|
223 |
- Trans->uas.request->REQ_METHOD==METHOD_INVITE) { |
|
224 |
- DBG("DBG: t_should_relay: 200 INV after final sent\n"); |
|
225 |
- *should_store=1; |
|
226 |
- return branch; |
|
227 |
- } else { |
|
228 |
- *should_store=0; |
|
229 |
- return -1; |
|
230 |
- } |
|
231 |
- } else { /* no final response sent yet */ |
|
232 |
- /* negative replies subject to fork picking */ |
|
233 |
- if (new_code >=300 ) { |
|
234 |
- *should_store=1; |
|
235 |
- /* if all_final return lowest */ |
|
236 |
- lowest_b=-1; lowest_s=999; |
|
237 |
- for ( b=0; b<Trans->nr_of_outgoings ; b++ ) { |
|
238 |
- /* "fake" for the currently processed branch */ |
|
239 |
- if (b==branch) { |
|
240 |
- if (new_code<lowest_s) { |
|
241 |
- lowest_b=b; |
|
242 |
- lowest_s=new_code; |
|
243 |
- } |
|
244 |
- continue; |
|
245 |
- } |
|
246 |
- /* there is still an unfinished UAC transaction; wait now! */ |
|
247 |
- if ( Trans->uac[b].status<200 ) |
|
248 |
- return -1; |
|
249 |
- if ( Trans->uac[b].status<lowest_s ) |
|
250 |
- { |
|
251 |
- lowest_b =b; |
|
252 |
- lowest_s = T->uac[b].status; |
|
253 |
- } |
|
254 |
- } |
|
255 |
- return lowest_b; |
|
256 |
- /* 1xx except 100 and 2xx will be relayed */ |
|
257 |
- } else if (new_code>100) { |
|
258 |
- *should_store=1; |
|
259 |
- return branch; |
|
260 |
- } |
|
261 |
- /* 100 won't be relayed */ |
|
262 |
- else { |
|
263 |
- if (!T->uac[branch].rpl_received) *should_store=1; |
|
264 |
- else *should_store=0; |
|
265 |
- if (Trans->uas.status==0) return branch; |
|
266 |
- else return -1; |
|
267 |
- } |
|
268 |
- } |
|
269 |
- |
|
270 |
- LOG(L_CRIT, "ERROR: Oh my gooosh! We don't know whether to relay\n"); |
|
271 |
- abort(); |
|
272 |
-} |
|
273 |
- |
|
274 |
- |
|
275 | 179 |
/* |
276 | 180 |
*/ |
277 | 181 |
int t_put_on_wait( struct cell *Trans ) |
... | ... |
@@ -325,147 +229,6 @@ int t_put_on_wait( struct cell *Trans ) |
325 | 229 |
|
326 | 230 |
|
327 | 231 |
|
328 |
-/* Builds a CANCEL request based on an INVITE request. CANCEL is send |
|
329 |
- * to same address as the INVITE */ |
|
330 |
-int t_build_and_send_CANCEL(struct cell *Trans,unsigned int branch) |
|
331 |
-{ |
|
332 |
- struct sip_msg *p_msg; |
|
333 |
- struct hdr_field *hdr; |
|
334 |
- char *cancel_buf, *p, *via; |
|
335 |
- unsigned int len, via_len; |
|
336 |
- |
|
337 |
- if ( !Trans->uac[branch].rpl_received ) |
|
338 |
- { |
|
339 |
- DBG("DEBUG: t_build_and_send_CANCEL: no response ever received" |
|
340 |
- " : dropping local cancel! \n"); |
|
341 |
- return 1; |
|
342 |
- } |
|
343 |
- |
|
344 |
- if (Trans->uac[branch].request.cancel!=NO_CANCEL) |
|
345 |
- { |
|
346 |
- DBG("DEBUG: t_build_and_send_CANCEL: branch (%d)was already canceled" |
|
347 |
- " : dropping local cancel! \n",branch); |
|
348 |
- return 1; |
|
349 |
- } |
|
350 |
- |
|
351 |
- cancel_buf = 0; |
|
352 |
- via = 0; |
|
353 |
- p_msg = Trans->uas.request; |
|
354 |
- |
|
355 |
- len = 0; |
|
356 |
- /*first line's len - CANCEL and INVITE has the same lenght */ |
|
357 |
- len += ( req_line(p_msg).version.s+req_line(p_msg).version.len)- |
|
358 |
- req_line(p_msg).method.s+CRLF_LEN; |
|
359 |
- /*check if the REQ URI was override */ |
|
360 |
- if (Trans->uac[branch].uri.s) |
|
361 |
- len += Trans->uac[branch].uri.len - req_line(p_msg).uri.len; |
|
362 |
- /*via*/ |
|
363 |
- if ( add_branch_label(Trans,p_msg,branch)==-1 ) |
|
364 |
- goto error; |
|
365 |
- via = via_builder( p_msg , &via_len ); |
|
366 |
- if (!via) |
|
367 |
- { |
|
368 |
- LOG(L_ERR, "ERROR: t_build_and_send_CANCEL: " |
|
369 |
- "no via header got from builder\n"); |
|
370 |
- goto error; |
|
371 |
- } |
|
372 |
- len+= via_len; |
|
373 |
- /*headers*/ |
|
374 |
- for ( hdr=p_msg->headers ; hdr ; hdr=hdr->next ) |
|
375 |
- if (hdr->type==HDR_FROM || hdr->type==HDR_CALLID || |
|
376 |
- hdr->type==HDR_CSEQ || hdr->type==HDR_TO ) |
|
377 |
- len += ((hdr->body.s+hdr->body.len ) - hdr->name.s ) + CRLF_LEN ; |
|
378 |
- /* User Agent header*/ |
|
379 |
- len += USER_AGENT_LEN + CRLF_LEN; |
|
380 |
- /* Content Lenght heder*/ |
|
381 |
- len += CONTENT_LEN_LEN + CRLF_LEN; |
|
382 |
- /* end of message */ |
|
383 |
- len += CRLF_LEN; |
|
384 |
- |
|
385 |
- cancel_buf=sh_malloc( len+1 ); |
|
386 |
- if (!cancel_buf) |
|
387 |
- { |
|
388 |
- LOG(L_ERR, "ERROR: t_build_and_send_CANCEL: cannot allocate memory\n"); |
|
389 |
- goto error; |
|
390 |
- } |
|
391 |
- p = cancel_buf; |
|
392 |
- |
|
393 |
- /* first line -> do we have a new URI? */ |
|
394 |
- if (Trans->uac[branch].uri.s) |
|
395 |
- { |
|
396 |
- append_mem_block(p,req_line(p_msg).method.s, |
|
397 |
- req_line(p_msg).uri.s-req_line(p_msg).method.s); |
|
398 |
- append_mem_block(p,Trans->uac[branch].uri.s, |
|
399 |
- Trans->uac[branch].uri.len); |
|
400 |
- append_mem_block(p,req_line(p_msg).uri.s+req_line(p_msg).uri.len, |
|
401 |
- req_line(p_msg).version.s+req_line(p_msg).version.len- |
|
402 |
- (req_line(p_msg).uri.s+req_line(p_msg).uri.len)) |
|
403 |
- }else{ |
|
404 |
- append_mem_block(p,req_line(p_msg).method.s, |
|
405 |
- req_line(p_msg).version.s+req_line(p_msg).version.len- |
|
406 |
- req_line(p_msg).method.s); |
|
407 |
- } |
|
408 |
- /* changhing method name*/ |
|
409 |
- memcpy(cancel_buf, CANCEL , CANCEL_LEN ); |
|
410 |
- append_mem_block(p,CRLF,CRLF_LEN); |
|
411 |
- /* insert our via */ |
|
412 |
- append_mem_block(p,via,via_len); |
|
413 |
- |
|
414 |
- /*other headers*/ |
|
415 |
- for ( hdr=p_msg->headers ; hdr ; hdr=hdr->next ) |
|
416 |
- { |
|
417 |
- if(hdr->type==HDR_FROM||hdr->type==HDR_CALLID||hdr->type==HDR_TO) |
|
418 |
- { |
|
419 |
- append_mem_block(p,hdr->name.s, |
|
420 |
- ((hdr->body.s+hdr->body.len)-hdr->name.s) ); |
|
421 |
- append_mem_block(p, CRLF, CRLF_LEN ); |
|
422 |
- }else if ( hdr->type==HDR_CSEQ ) |
|
423 |
- { |
|
424 |
- append_mem_block(p,hdr->name.s, |
|
425 |
- ((((struct cseq_body*)hdr->parsed)->method.s)-hdr->name.s)); |
|
426 |
- append_mem_block(p, CANCEL CRLF, CANCEL_LEN +CRLF_LEN ); |
|
427 |
- } |
|
428 |
-} |
|
429 |
- |
|
430 |
- /* User Agent header */ |
|
431 |
- append_mem_block(p,USER_AGENT,USER_AGENT_LEN); |
|
432 |
- append_mem_block(p,CRLF,CRLF_LEN); |
|
433 |
- /* Content Lenght header*/ |
|
434 |
- append_mem_block(p,CONTENT_LEN,CONTENT_LEN_LEN); |
|
435 |
- append_mem_block(p,CRLF,CRLF_LEN); |
|
436 |
- /* end of message */ |
|
437 |
- append_mem_block(p,CRLF,CRLF_LEN); |
|
438 |
- *p=0; |
|
439 |
- |
|
440 |
- if (Trans->uac[branch].request.cancel) { |
|
441 |
- shm_free( cancel_buf ); |
|
442 |
- LOG(L_WARN, "send_cancel: Warning: CANCEL already sent out\n"); |
|
443 |
- goto error; |
|
444 |
- } |
|
445 |
- |
|
446 |
- Trans->uac[branch].request.activ_type = TYPE_LOCAL_CANCEL; |
|
447 |
- Trans->uac[branch].request.cancel = cancel_buf; |
|
448 |
- Trans->uac[branch].request.cancel_len = len; |
|
449 |
- |
|
450 |
- /*sets and starts the FINAL RESPONSE timer */ |
|
451 |
- set_timer(hash_table,&(Trans->uac[branch].request.fr_timer),FR_TIMER_LIST); |
|
452 |
- /* sets and starts the RETRANS timer */ |
|
453 |
- Trans->uac[branch].request.retr_list = RT_T1_TO_1; |
|
454 |
- set_timer(hash_table,&(Trans->uac[branch].request.retr_timer),RT_T1_TO_1); |
|
455 |
- DBG("DEBUG: T_build_and_send_CANCEL : sending cancel...\n"); |
|
456 |
- SEND_CANCEL_BUFFER( &(Trans->uac[branch].request) ); |
|
457 |
- |
|
458 |
- pkg_free(via); |
|
459 |
- return 1; |
|
460 |
-error: |
|
461 |
- if (via) pkg_free(via); |
|
462 |
- return -1; |
|
463 |
-} |
|
464 |
- |
|
465 |
- |
|
466 |
- |
|
467 |
- |
|
468 |
- |
|
469 | 232 |
|
470 | 233 |
void delete_cell( struct cell *p_cell ) |
471 | 234 |
{ |
... | ... |
@@ -524,492 +287,3 @@ void delete_cell( struct cell *p_cell ) |
524 | 287 |
} |
525 | 288 |
|
526 | 289 |
|
527 |
- |
|
528 |
- |
|
529 |
-/* Returns -1 = error |
|
530 |
- 0 = OK |
|
531 |
-*/ |
|
532 |
-int get_ip_and_port_from_uri( str *uri , unsigned int *param_ip, unsigned int *param_port) |
|
533 |
-{ |
|
534 |
- struct hostent *nhost; |
|
535 |
- unsigned int ip, port; |
|
536 |
- struct sip_uri parsed_uri; |
|
537 |
- int err; |
|
538 |
-#ifdef DNS_IP_HACK |
|
539 |
- int len; |
|
540 |
-#endif |
|
541 |
- |
|
542 |
- /* parsing the request uri in order to get host and port */ |
|
543 |
- if (parse_uri( uri->s , uri->len , &parsed_uri )<0) |
|
544 |
- { |
|
545 |
- LOG(L_ERR, "ERROR: get_ip_and_port_from_uri: " |
|
546 |
- "unable to parse destination uri: %.*s\n", uri->len, uri->s ); |
|
547 |
- goto error; |
|
548 |
- } |
|
549 |
- |
|
550 |
- /* getting the port */ |
|
551 |
- if ( parsed_uri.port.s==0 || parsed_uri.port.len==0 ) |
|
552 |
- port = SIP_PORT; |
|
553 |
- else{ |
|
554 |
- port = str2s( (unsigned char*) parsed_uri.port.s, parsed_uri.port.len, |
|
555 |
- &err ); |
|
556 |
- if ( err<0 ){ |
|
557 |
- LOG(L_ERR, "ERROR: get_ip_and_port_from_uri: converting port " |
|
558 |
- "from str to int failed; using default SIP port\n\turi:%.*s\n", |
|
559 |
- uri->len, uri->s ); |
|
560 |
- port = SIP_PORT; |
|
561 |
- } |
|
562 |
- } |
|
563 |
- port = htons(port); |
|
564 |
- |
|
565 |
- /* getting host address*/ |
|
566 |
-#ifdef DNS_IP_HACK |
|
567 |
- len=strlen( parsed_uri.host.s ); |
|
568 |
- ip=str2ip( (unsigned char*)parsed_uri.host.s, len, &err); |
|
569 |
- if (err==0) |
|
570 |
- goto success; |
|
571 |
-#endif |
|
572 |
- /* fail over to normal lookup */ |
|
573 |
- nhost = gethostbyname( parsed_uri.host.s ); |
|
574 |
- if ( !nhost ) |
|
575 |
- { |
|
576 |
- LOG(L_ERR, "ERROR: get_ip_and_port_from_uri: " |
|
577 |
- "cannot resolve host in uri: %.*s\n", uri->len, uri->s ); |
|
578 |
- free_uri(&parsed_uri); |
|
579 |
- goto error; |
|
580 |
- } |
|
581 |
- memcpy(&ip, nhost->h_addr_list[0], sizeof(unsigned int)); |
|
582 |
- |
|
583 |
- |
|
584 |
-success: |
|
585 |
- free_uri(&parsed_uri); |
|
586 |
- *param_ip = ip; |
|
587 |
- *param_port = port; |
|
588 |
- return 0; |
|
589 |
- |
|
590 |
-error: |
|
591 |
- *param_ip = 0; |
|
592 |
- *param_port = 0; |
|
593 |
- return -1; |
|
594 |
-} |
|
595 |
- |
|
596 |
- |
|
597 |
- |
|
598 |
- |
|
599 |
-int t_add_fork( unsigned int ip, unsigned int port, char* uri_s, |
|
600 |
- unsigned int uri_len, enum fork_type type, unsigned char free_flag) |
|
601 |
-{ |
|
602 |
- unsigned int pos=0; |
|
603 |
- char *foo=0; |
|
604 |
- |
|
605 |
- switch (type) |
|
606 |
- { |
|
607 |
- case DEFAULT: |
|
608 |
- if (nr_forks+1>=MAX_FORK) |
|
609 |
- { |
|
610 |
- LOG(L_ERR,"ERROR:t_add_fork: trying to add new fork ->" |
|
611 |
- " MAX_FORK exceded\n"); |
|
612 |
- return -1; |
|
613 |
- } |
|
614 |
- pos = ++nr_forks; |
|
615 |
- break; |
|
616 |
- case NO_RESPONSE: |
|
617 |
- if (t_forks[NO_RPL_BRANCH].ip) |
|
618 |
- LOG(L_WARN,"WARNING:t_add_fork: trying to add NO_RPL fork ->" |
|
619 |
- " it was set before -> overriding\n"); |
|
620 |
- if (uri_s && uri_len) |
|
621 |
- { |
|
622 |
- foo = (char*)shm_malloc(uri_len); |
|
623 |
- if (!foo) |
|
624 |
- { |
|
625 |
- LOG(L_ERR,"ERROR:t_add_fork: cannot get free memory\n"); |
|
626 |
- return -1; |
|
627 |
- } |
|
628 |
- memcpy(foo,uri_s,uri_len); |
|
629 |
- } |
|
630 |
- if (free_flag && uri_s) |
|
631 |
- pkg_free(uri_s); |
|
632 |
- uri_s = foo; |
|
633 |
- free_flag = 0; |
|
634 |
- pos = NO_RPL_BRANCH; |
|
635 |
- } |
|
636 |
- t_forks[pos].ip = ip; |
|
637 |
- t_forks[pos].port = port; |
|
638 |
- if (uri_s && uri_len) |
|
639 |
- { |
|
640 |
- t_forks[pos].free_flag = free_flag; |
|
641 |
- t_forks[pos].uri.len = uri_len; |
|
642 |
- t_forks[pos].uri.s = uri_s; |
|
643 |
- } |
|
644 |
- |
|
645 |
- return 1; |
|
646 |
-} |
|
647 |
- |
|
648 |
- |
|
649 |
- |
|
650 |
- |
|
651 |
-int t_clear_forks( ) |
|
652 |
-{ |
|
653 |
- int i; |
|
654 |
- |
|
655 |
- DBG("DEBUG: t_clear_forks: clearing tabel...\n"); |
|
656 |
- for(i=1;i<nr_forks;i++) |
|
657 |
- if (t_forks[i].free_flag && t_forks[i].uri.s) |
|
658 |
- pkg_free(t_forks[i].uri.s); |
|
659 |
- memset( t_forks, 0, sizeof(t_forks)); |
|
660 |
- nr_forks = 0; |
|
661 |
- return 1; |
|
662 |
-} |
|
663 |
- |
|
664 |
- |
|
665 |
- |
|
666 |
- |
|
667 |
- |
|
668 |
-/*---------------------------TIMERS FUNCTIONS-------------------------------*/ |
|
669 |
- |
|
670 |
- |
|
671 |
- |
|
672 |
- |
|
673 |
- |
|
674 |
-inline void retransmission_handler( void *attr) |
|
675 |
-{ |
|
676 |
- struct retr_buf* r_buf ; |
|
677 |
- enum lists id; |
|
678 |
- |
|
679 |
- r_buf = (struct retr_buf*)attr; |
|
680 |
-#ifdef EXTRA_DEBUG |
|
681 |
- if (r_buf->my_T->damocles) { |
|
682 |
- LOG( L_ERR, "ERROR: transaction %p scheduled for deletion and" |
|
683 |
- " called from RETR timer\n",r_buf->my_T); |
|
684 |
- abort(); |
|
685 |
- } |
|
686 |
-#endif |
|
687 |
- |
|
688 |
- /*the transaction is already removed from RETRANSMISSION_LIST by timer*/ |
|
689 |
- /* retransmision */ |
|
690 |
- DBG("DEBUG: retransmission_handler : resending (t=%p)\n", r_buf->my_T); |
|
691 |
- switch ( r_buf->activ_type ) |
|
692 |
- { |
|
693 |
- case (TYPE_REQUEST): |
|
694 |
- SEND_BUFFER( r_buf ); |
|
695 |
- break; |
|
696 |
- case (TYPE_LOCAL_CANCEL): |
|
697 |
- SEND_CANCEL_BUFFER( r_buf ); |
|
698 |
- break; |
|
699 |
- default: |
|
700 |
- T=r_buf->my_T; |
|
701 |
- t_retransmit_reply(); |
|
702 |
- } |
|
703 |
- |
|
704 |
- id = r_buf->retr_list; |
|
705 |
- r_buf->retr_list = id < RT_T2 ? id + 1 : RT_T2; |
|
706 |
- |
|
707 |
- set_timer(hash_table,&(r_buf->retr_timer),id < RT_T2 ? id + 1 : RT_T2 ); |
|
708 |
- |
|
709 |
- DBG("DEBUG: retransmission_handler : done\n"); |
|
710 |
-} |
|
711 |
- |
|
712 |
- |
|
713 |
- |
|
714 |
- |
|
715 |
-inline void final_response_handler( void *attr) |
|
716 |
-{ |
|
717 |
- struct retr_buf* r_buf = (struct retr_buf*)attr; |
|
718 |
- |
|
719 |
-#ifdef EXTRA_DEBUG |
|
720 |
- if (r_buf->my_T->damocles) |
|
721 |
- { |
|
722 |
- LOG( L_ERR, "ERROR: transaction %p scheduled for deletion and" |
|
723 |
- " called from FR timer\n",r_buf->my_T); |
|
724 |
- abort(); |
|
725 |
- } |
|
726 |
-#endif |
|
727 |
- |
|
728 |
- /* the transaction is already removed from FR_LIST by the timer */ |
|
729 |
- if (r_buf->activ_type==TYPE_LOCAL_CANCEL) |
|
730 |
- { |
|
731 |
- DBG("DEBUG: FR_handler: stop retransmission for Local Cancel\n"); |
|
732 |
- reset_timer( hash_table , &(r_buf->retr_timer) ); |
|
733 |
- return; |
|
734 |
- } |
|
735 |
- /* send a 408 */ |
|
736 |
- if ( r_buf->my_T->uac[r_buf->branch].status<200 |
|
737 |
-#ifdef SILENT_FR |
|
738 |
- && (r_buf->my_T->nr_of_outgoings>1 /*if we have forked*/ |
|
739 |
- || r_buf->my_T->uas.request->first_line.u.request.method_value!= |
|
740 |
- METHOD_INVITE /*if is not an INVITE */ |
|
741 |
- || r_buf->my_T->uac[r_buf->my_T->nr_of_outgoings].uri.s |
|
742 |
- /*if "no on no response" was set*/ |
|
743 |
- || r_buf->my_T->uac[r_buf->branch].rpl_received==0 |
|
744 |
- /*if no reply was received*/ |
|
745 |
- ) |
|
746 |
-#endif |
|
747 |
- ) |
|
748 |
- { |
|
749 |
- DBG("DEBUG: FR_handler:stop retr. and send CANCEL (%p)\n",r_buf->my_T); |
|
750 |
- reset_timer( hash_table, &(r_buf->retr_timer) ); |
|
751 |
- t_build_and_send_CANCEL( r_buf->my_T ,r_buf->branch); |
|
752 |
- /* dirty hack:t_send_reply would increase ref_count which would indeed |
|
753 |
- result in refcount++ which would not -- until timer processe's |
|
754 |
- T changes again; currently only on next call to t_send_reply from |
|
755 |
- FR timer; thus I fake the values now to avoid recalculating T |
|
756 |
- and refcount++ JKU */ |
|
757 |
- T=r_buf->my_T; |
|
758 |
- global_msg_id=T->uas.request->id; |
|
759 |
- DBG("DEBUG: FR_handler: send 408 (%p)\n", r_buf->my_T); |
|
760 |
- t_send_reply( r_buf->my_T->uas.request, 408, "Request Timeout", |
|
761 |
- r_buf->branch); |
|
762 |
- }else{ |
|
763 |
- /* put it on WT_LIST - transaction is over */ |
|
764 |
- DBG("DEBUG: final_response_handler:-> put on wait" |
|
765 |
- " (t=%p)\n", r_buf->my_T); |
|
766 |
- t_put_on_wait( r_buf->my_T ); |
|
767 |
- } |
|
768 |
- DBG("DEBUG: final_response_handler : done\n"); |
|
769 |
-} |
|
770 |
- |
|
771 |
- |
|
772 |
- |
|
773 |
- |
|
774 |
-inline void wait_handler( void *attr) |
|
775 |
-{ |
|
776 |
- struct cell *p_cell = (struct cell*)attr; |
|
777 |
- |
|
778 |
-#ifdef EXTRA_DEBUG |
|
779 |
- if (p_cell->damocles) { |
|
780 |
- LOG( L_ERR, "ERROR: transaction %p scheduled for deletion and" |
|
781 |
- " called from WAIT timer\n",p_cell); |
|
782 |
- abort(); |
|
783 |
- } |
|
784 |
-#endif |
|
785 |
- |
|
786 |
- /* the transaction is already removed from WT_LIST by the timer */ |
|
787 |
- /* the cell is removed from the hash table */ |
|
788 |
- DBG("DEBUG: wait_handler : removing %p from table \n", p_cell ); |
|
789 |
- remove_from_hash_table( hash_table, p_cell ); |
|
790 |
- /* jku: no more here -- we do it when we put a transaction on wait */ |
|
791 |
- DBG("DEBUG: wait_handler : stopping all timers\n"); |
|
792 |
- reset_retr_timers(hash_table,p_cell) ; |
|
793 |
- /* put it on DEL_LIST - sch for del */ |
|
794 |
-#ifdef EXTRA_DEBUG |
|
795 |
- p_cell->damocles = 1; |
|
796 |
-#endif |
|
797 |
- delete_cell( p_cell ); |
|
798 |
- DBG("DEBUG: wait_handler : done\n"); |
|
799 |
-} |
|
800 |
- |
|
801 |
- |
|
802 |
- |
|
803 |
- |
|
804 |
-inline void delete_handler( void *attr) |
|
805 |
-{ |
|
806 |
- struct cell *p_cell = (struct cell*)attr; |
|
807 |
- |
|
808 |
- DBG("DEBUG: delete_handler : removing %p \n", p_cell ); |
|
809 |
-#ifdef EXTRA_DEBUG |
|
810 |
- if (p_cell->damocles==0) { |
|
811 |
- LOG( L_ERR, "ERROR: transaction %p not scheduled for deletion" |
|
812 |
- " and called from DELETE timer\n",p_cell); |
|
813 |
- abort(); |
|
814 |
- } |
|
815 |
-#endif |
|
816 |
- delete_cell( p_cell ); |
|
817 |
- DBG("DEBUG: delete_handler : done\n"); |
|
818 |
-} |
|
819 |
- |
|
820 |
- |
|
821 |
- |
|
822 |
- |
|
823 |
-#define run_handler_for_each( _tl , _handler ) \ |
|
824 |
- while ((_tl))\ |
|
825 |
- {\ |
|
826 |
- /* reset the timer list linkage */\ |
|
827 |
- tmp_tl = (_tl)->next_tl;\ |
|
828 |
- (_tl)->next_tl = (_tl)->prev_tl = 0;\ |
|
829 |
- DBG("DEBUG: timer routine:%d,tl=%p next=%p\n",\ |
|
830 |
- id,(_tl),tmp_tl);\ |
|
831 |
- (_handler)( (_tl)->payload );\ |
|
832 |
- (_tl) = tmp_tl;\ |
|
833 |
- } |
|
834 |
- |
|
835 |
- |
|
836 |
- |
|
837 |
- |
|
838 |
-void timer_routine(unsigned int ticks , void * attr) |
|
839 |
-{ |
|
840 |
- struct s_table *hash_table = (struct s_table *)attr; |
|
841 |
- struct timer_link *tl, *tmp_tl; |
|
842 |
- int id; |
|
843 |
- |
|
844 |
-#ifdef BOGDAN_TRIFLE |
|
845 |
- DBG(" %d \n",ticks); |
|
846 |
-#endif |
|
847 |
- |
|
848 |
- for( id=0 ; id<NR_OF_TIMER_LISTS ; id++ ) |
|
849 |
- { |
|
850 |
- /* to waste as little time in lock as possible, detach list |
|
851 |
- with expired items and process them after leaving the lock */ |
|
852 |
- tl=check_and_split_time_list( &(hash_table->timers[ id ]), ticks); |
|
853 |
- /* process items now */ |
|
854 |
- switch (id) |
|
855 |
- { |
|
856 |
- case FR_TIMER_LIST: |
|
857 |
- case FR_INV_TIMER_LIST: |
|
858 |
- run_handler_for_each(tl,final_response_handler); |
|
859 |
- break; |
|
860 |
- case RT_T1_TO_1: |
|
861 |
- case RT_T1_TO_2: |
|
862 |
- case RT_T1_TO_3: |
|
863 |
- case RT_T2: |
|
864 |
- run_handler_for_each(tl,retransmission_handler); |
|
865 |
- break; |
|
866 |
- case WT_TIMER_LIST: |
|
867 |
- run_handler_for_each(tl,wait_handler); |
|
868 |
- break; |
|
869 |
- case DELETE_LIST: |
|
870 |
- run_handler_for_each(tl,delete_handler); |
|
871 |
- break; |
|
872 |
- } |
|
873 |
- } |
|
874 |
-} |
|
875 |
- |
|
876 |
- |
|
877 |
- |
|
878 |
- |
|
879 |
- |
|
880 |
- |
|
881 |
- |
|
882 |
-/* Builds an ACK request based on an INVITE request. ACK is send |
|
883 |
- * to same address */ |
|
884 |
-char *build_ack(struct sip_msg* rpl,struct cell *trans,int branch,int *ret_len) |
|
885 |
-{ |
|
886 |
- struct sip_msg *p_msg , *r_msg; |
|
887 |
- struct hdr_field *hdr; |
|
888 |
- char *ack_buf, *p, *via; |
|
889 |
- unsigned int len, via_len; |
|
890 |
- |
|
891 |
- ack_buf = 0; |
|
892 |
- via =0; |
|
893 |
- p_msg = trans->uas.request; |
|
894 |
- r_msg = rpl; |
|
895 |
- |
|
896 |
- if ( parse_headers(rpl,HDR_TO)==-1 || !rpl->to ) |
|
897 |
- { |
|
898 |
- LOG(L_ERR, "ERROR: t_build_ACK: " |
|
899 |
- "cannot generate a HBH ACK if key HFs in reply missing\n"); |
|
900 |
- goto error; |
|
901 |
- } |
|
902 |
- |
|
903 |
- len = 0; |
|
904 |
- /*first line's len */ |
|
905 |
- len += 4/*reply code and one space*/+ |
|
906 |
- p_msg->first_line.u.request.version.len+CRLF_LEN; |
|
907 |
- /*uri's len*/ |
|
908 |
- if (trans->uac[branch].uri.s) |
|
909 |
- len += trans->uac[branch].uri.len +1; |
|
910 |
- else |
|
911 |
- len += p_msg->first_line.u.request.uri.len +1; |
|
912 |
- /*adding branch param*/ |
|
913 |
- if ( add_branch_label( trans , trans->uas.request , branch)==-1 ) |
|
914 |
- goto error; |
|
915 |
- /*via*/ |
|
916 |
- via = via_builder( p_msg , &via_len ); |
|
917 |
- if (!via) |
|
918 |
- { |
|
919 |
- LOG(L_ERR, "ERROR: t_build_ACK: " |
|
920 |
- "no via header got from builder\n"); |
|
921 |
- goto error; |
|
922 |
- } |
|
923 |
- len+= via_len; |
|
924 |
- /*headers*/ |
|
925 |
- for ( hdr=p_msg->headers ; hdr ; hdr=hdr->next ) |
|
926 |
- if (hdr->type==HDR_FROM||hdr->type==HDR_CALLID||hdr->type==HDR_CSEQ) |
|
927 |
- len += ((hdr->body.s+hdr->body.len ) - hdr->name.s ) + CRLF_LEN ; |
|
928 |
- else if ( hdr->type==HDR_TO ) |
|
929 |
- len += ((r_msg->to->body.s+r_msg->to->body.len ) - |
|
930 |
- r_msg->to->name.s ) + CRLF_LEN ; |
|
931 |
- /* CSEQ method : from INVITE-> ACK */ |
|
932 |
- len -= 3 ; |
|
933 |
- /* end of message */ |
|
934 |
- len += CRLF_LEN; /*new line*/ |
|
935 |
- |
|
936 |
- ack_buf = sh_malloc(len+1); |
|
937 |
- if (!ack_buf) |
|
938 |
- { |
|
939 |
- LOG(L_ERR, "ERROR: t_build_and_ACK: cannot allocate memory\n"); |
|
940 |
- goto error1; |
|
941 |
- } |
|
942 |
- p = ack_buf; |
|
943 |
- |
|
944 |
- /* first line */ |
|
945 |
- memcpy( p , "ACK " , 4); |
|
946 |
- p += 4; |
|
947 |
- /* uri */ |
|
948 |
- if ( trans->uac[branch].uri.s ) |
|
949 |
- { |
|
950 |
- memcpy(p,trans->uac[branch].uri.s,trans->uac[branch].uri.len); |
|
951 |
- p +=trans->uac[branch].uri.len; |
|
952 |
- }else{ |
|
953 |
- memcpy(p,p_msg->orig+(p_msg->first_line.u.request.uri.s-p_msg->buf), |
|
954 |
- p_msg->first_line.u.request.uri.len ); |
|
955 |
- p += p_msg->first_line.u.request.uri.len; |
|
956 |
- } |
|
957 |
- /* SIP version */ |
|
958 |
- *(p++) = ' '; |
|
959 |
- memcpy(p,p_msg->orig+(p_msg->first_line.u.request.version.s-p_msg->buf), |
|
960 |
- p_msg->first_line.u.request.version.len ); |
|
961 |
- p += p_msg->first_line.u.request.version.len; |
|
962 |
- memcpy( p, CRLF, CRLF_LEN ); |
|
963 |
- p+=CRLF_LEN; |
|
964 |
- |
|
965 |
- /* insert our via */ |
|
966 |
- memcpy( p , via , via_len ); |
|
967 |
- p += via_len; |
|
968 |
- |
|
969 |
- /*other headers*/ |
|
970 |
- for ( hdr=p_msg->headers ; hdr ; hdr=hdr->next ) |
|
971 |
- { |
|
972 |
- if ( hdr->type==HDR_FROM || hdr->type==HDR_CALLID ) |
|
973 |
- { |
|
974 |
- memcpy( p , p_msg->orig+(hdr->name.s-p_msg->buf) , |
|
975 |
- ((hdr->body.s+hdr->body.len ) - hdr->name.s ) ); |
|
976 |
- p += ((hdr->body.s+hdr->body.len ) - hdr->name.s ); |
|
977 |
- memcpy( p, CRLF, CRLF_LEN ); |
|
978 |
- p+=CRLF_LEN; |
|
979 |
- } |
|
980 |
- else if ( hdr->type==HDR_TO ) |
|
981 |
- { |
|
982 |
- memcpy( p , r_msg->orig+(r_msg->to->name.s-r_msg->buf) , |
|
983 |
- ((r_msg->to->body.s+r_msg->to->body.len)-r_msg->to->name.s)); |
|
984 |
- p+=((r_msg->to->body.s+r_msg->to->body.len)-r_msg->to->name.s); |
|
985 |
- memcpy( p, CRLF, CRLF_LEN ); |
|
986 |
- p+=CRLF_LEN; |
|
987 |
- } |
|
988 |
- else if ( hdr->type==HDR_CSEQ ) |
|
989 |
- { |
|
990 |
- memcpy( p , p_msg->orig+(hdr->name.s-p_msg->buf) , |
|
991 |
- ((((struct cseq_body*)hdr->parsed)->method.s)-hdr->name.s)); |
|
992 |
- p+=((((struct cseq_body*)hdr->parsed)->method.s)-hdr->name.s); |
|
993 |
- memcpy( p , "ACK" CRLF, 3+CRLF_LEN ); |
|
994 |
- p += 3+CRLF_LEN; |
|
995 |
- } |
|
996 |
- } |
|
997 |
- |
|
998 |
- /* end of message */ |
|
999 |
- memcpy( p , CRLF , CRLF_LEN ); |
|
1000 |
- p += CRLF_LEN; |
|
1001 |
- |
|
1002 |
- pkg_free( via ); |
|
1003 |
- DBG("DEBUG: t_build_ACK: ACK generated\n"); |
|
1004 |
- |
|
1005 |
- *(ret_len) = p-ack_buf; |
|
1006 |
- return ack_buf; |
|
1007 |
- |
|
1008 |
-error1: |
|
1009 |
- pkg_free(via ); |
|
1010 |
-error: |
|
1011 |
- return 0; |
|
1012 |
-} |
|
1013 |
- |
|
1014 |
- |
|
1015 |
- |
... | ... |
@@ -17,12 +17,14 @@ |
17 | 17 |
#include "../../timer.h" |
18 | 18 |
#include "../../forward.h" |
19 | 19 |
#include "../../mem/mem.h" |
20 |
- |
|
21 | 20 |
#include "../../md5utils.h" |
21 |
+#include "../../ip_addr.h" |
|
22 | 22 |
|
23 | 23 |
#include "config.h" |
24 | 24 |
#include "lock.h" |
25 | 25 |
#include "timer.h" |
26 |
+#include "sh_malloc.h" |
|
27 |
+#include "sip_msg.h" |
|
26 | 28 |
|
27 | 29 |
|
28 | 30 |
struct s_table; |
... | ... |
@@ -30,27 +32,10 @@ struct timer; |
30 | 32 |
struct entry; |
31 | 33 |
struct cell; |
32 | 34 |
|
33 |
-struct fork |
|
34 |
-{ |
|
35 |
- unsigned int ip,port; |
|
36 |
- unsigned char free_flag; |
|
37 |
- str uri; |
|
38 |
- |
|
39 |
-}; |
|
40 |
- |
|
41 |
- |
|
42 | 35 |
extern struct cell *T; |
43 | 36 |
extern unsigned int global_msg_id; |
44 | 37 |
extern struct s_table* hash_table; |
45 |
-extern struct fork t_forks[ NR_OF_CLIENTS ]; |
|
46 |
-extern unsigned int nr_forks; |
|
47 |
- |
|
48 |
- |
|
49 |
-#include "sh_malloc.h" |
|
50 | 38 |
|
51 |
-#include "timer.h" |
|
52 |
-#include "lock.h" |
|
53 |
-#include "sip_msg.h" |
|
54 | 39 |
|
55 | 40 |
|
56 | 41 |
#define LOCK_REPLIES(_t) lock(&(_t)->reply_mutex ) |
... | ... |
@@ -66,17 +51,35 @@ extern unsigned int nr_forks; |
66 | 51 |
for reducing time spend in REPLIES locks |
67 | 52 |
*/ |
68 | 53 |
|
69 |
-#define SEND_PR_BUFFER(_rb,_bf,_le ) \ |
|
70 |
- {\ |
|
71 |
- if ((_bf) && (_le) && (_bf) ) {\ |
|
72 |
- udp_send( (_bf), (_le), (struct sockaddr*)&((_rb)->to) , \ |
|
73 |
- sizeof(struct sockaddr_in) ); \ |
|
74 |
- }else{ \ |
|
75 |
- LOG(L_CRIT,"ERROR: sending an empty buffer from %s (%d)\n",\ |
|
76 |
- __FUNCTION__, __LINE__ );\ |
|
77 |
- }\ |
|
54 |
+inline static int send_pr_buffer( struct retr_buf *rb, |
|
55 |
+ void *buf, int len, char *function, int line ) |
|
56 |
+{ |
|
57 |
+ if (buf && len && rb ) |
|
58 |
+ return udp_send( rb->send_sock, buf, |
|
59 |
+ len, &rb->to, sizeof(union sockaddr_union) ) ; |
|
60 |
+ else { |
|
61 |
+ LOG(L_CRIT, "ERROR: sending an empty buffer from %s (%d)\n", |
|
62 |
+ function, line ); |
|
63 |
+ return -1; |
|
78 | 64 |
} |
65 |
+} |
|
66 |
+ |
|
67 |
+#define SEND_PR_BUFFER(_rb,_bf,_le ) \ |
|
68 |
+ send_pr_buffer( (_rb), (_bf), (_le), __FUNCTION__, __LINE__ ) |
|
79 | 69 |
|
70 |
+/* |
|
71 |
+#define SEND_PR_BUFFER(_rb,_bf,_le ) \ |
|
72 |
+ ( ((_bf) && (_le) && (_bf)) ? \ |
|
73 |
+ udp_send( (_bf), (_le), &((_rb)->to), sizeof(union sockaddr_union) ) : \ |
|
74 |
+ log_send_error( __FUNCTION__, __LINE__ ) ) |
|
75 |
+*/ |
|
76 |
+ |
|
77 |
+/* just for understanding of authors of the following macros, who did not |
|
78 |
+ include 'PR' in macro names though they use 'PR' macro: PR stands for |
|
79 |
+ PRIVATE and indicates usage of memory buffers in PRIVATE memory space, |
|
80 |
+ where -- as opposed to SHARED memory space -- no concurrent memory |
|
81 |
+ access can occur and thus no locking is needed ! -jiri |
|
82 |
+*/ |
|
80 | 83 |
#define SEND_ACK_BUFFER( _rb ) \ |
81 | 84 |
SEND_PR_BUFFER( (_rb) , (_rb)->ack , (_rb)->ack_len ) |
82 | 85 |
|
... | ... |
@@ -134,9 +137,10 @@ extern unsigned int nr_forks; |
134 | 137 |
|
135 | 138 |
|
136 | 139 |
|
137 |
- |
|
140 |
+/* |
|
138 | 141 |
enum addifnew_status { AIN_ERROR, AIN_RETR, AIN_NEW, AIN_NEWACK, |
139 | 142 |
AIN_OLDACK, AIN_RTRACK } ; |
143 |
+*/ |
|
140 | 144 |
|
141 | 145 |
|
142 | 146 |
int tm_startup(); |
... | ... |
@@ -165,8 +169,10 @@ int t_check( struct sip_msg* , int *branch , int* is_cancel); |
165 | 169 |
* 1 - forward successfull |
166 | 170 |
* -1 - error during forward |
167 | 171 |
*/ |
172 |
+/* v6; -jiri |
|
168 | 173 |
int t_forward( struct sip_msg* p_msg , unsigned int dst_ip , |
169 | 174 |
unsigned int dst_port); |
175 |
+*/ |
|
170 | 176 |
|
171 | 177 |
|
172 | 178 |
|
... | ... |
@@ -175,7 +181,9 @@ int t_forward( struct sip_msg* p_msg , unsigned int dst_ip , |
175 | 181 |
* 1 - forward successfull |
176 | 182 |
* -1 - error during forward |
177 | 183 |
*/ |
184 |
+/* v6; -jiri |
|
178 | 185 |
int t_forward_uri( struct sip_msg* p_msg ); |
186 |
+*/ |
|
179 | 187 |
|
180 | 188 |
|
181 | 189 |
|
... | ... |
@@ -239,11 +247,16 @@ int t_unref( /* struct sip_msg* p_msg */ ); |
239 | 247 |
|
240 | 248 |
|
241 | 249 |
|
242 |
- |
|
250 |
+/* v6; -jiri |
|
243 | 251 |
int t_forward_nonack( struct sip_msg* p_msg , unsigned int dest_ip_param , |
244 | 252 |
unsigned int dest_port_param ); |
245 | 253 |
int t_forward_ack( struct sip_msg* p_msg , unsigned int dest_ip_param , |
246 | 254 |
unsigned int dest_port_param ); |
255 |
+*/ |
|
256 |
+int t_forward_nonack( struct sip_msg* p_msg, struct proxy_l * p ); |
|
257 |
+int t_forward_ack( struct sip_msg* p_msg ); |
|
258 |
+ |
|
259 |
+ |
|
247 | 260 |
int forward_serial_branch(struct cell* Trans,int branch); |
248 | 261 |
struct cell* t_lookupOriginalT( struct s_table* hash_table, |
249 | 262 |
struct sip_msg* p_msg ); |
... | ... |
@@ -264,10 +277,11 @@ int get_ip_and_port_from_uri( str* uri , unsigned int *param_ip, |
264 | 277 |
int t_build_and_send_CANCEL(struct cell *Trans, unsigned int branch); |
265 | 278 |
char *build_ack( struct sip_msg* rpl, struct cell *trans, int branch , |
266 | 279 |
int *ret_len); |
267 |
-enum addifnew_status t_addifnew( struct sip_msg* p_msg ); |
|
268 |
-int t_add_fork( unsigned int ip , unsigned int port, char* uri_s, |
|
269 |
- unsigned int uri_len, enum fork_type type, unsigned char free_flag); |
|
270 |
-int t_clear_forks( ); |
|
280 |
+ |
|
281 |
+int t_addifnew( struct sip_msg* p_msg ); |
|
282 |
+ |
|
283 |
+void timer_routine(unsigned int, void*); |
|
284 |
+ |
|
271 | 285 |
|
272 | 286 |
|
273 | 287 |
|
... | ... |
@@ -356,7 +370,9 @@ static inline void reset_retr_timers( struct s_table *h_table, |
356 | 370 |
DBG("DEBUG:stop_RETR_and_FR_timers : timers stopped\n"); |
357 | 371 |
} |
358 | 372 |
|
373 |
+void delete_cell( struct cell *p_cell ); |
|
359 | 374 |
|
375 |
+int t_newtran( struct sip_msg* p_msg ); |
|
360 | 376 |
|
361 | 377 |
#endif |
362 | 378 |
|
... | ... |
@@ -3,13 +3,14 @@ |
3 | 3 |
* |
4 | 4 |
*/ |
5 | 5 |
|
6 |
-#include "hash_func.h" |
|
7 |
-#include "t_funcs.h" |
|
8 | 6 |
#include "../../dprint.h" |
9 | 7 |
#include "../../config.h" |
10 | 8 |
#include "../../parser/parser_f.h" |
11 | 9 |
#include "../../ut.h" |
12 | 10 |
#include "../../timer.h" |
11 |
+#include "hash_func.h" |
|
12 |
+#include "t_funcs.h" |
|
13 |
+#include "t_fork.h" |
|
13 | 14 |
|
14 | 15 |
#include "t_hooks.h" |
15 | 16 |
|
... | ... |
@@ -29,8 +30,11 @@ |
29 | 30 |
* 1 - forward successfull |
30 | 31 |
* -1 - error during forward |
31 | 32 |
*/ |
32 |
-int t_forward_nonack( struct sip_msg* p_msg , unsigned int dest_ip_param , |
|
33 |
+int t_forward_nonack( struct sip_msg* p_msg , |
|
34 |
+ struct proxy_l * p ) |
|
35 |
+/* v6; -jiri unsigned int dest_ip_param , |
|
33 | 36 |
unsigned int dest_port_param ) |
37 |
+*/ |
|
34 | 38 |
{ |
35 | 39 |
int branch; |
36 | 40 |
unsigned int len; |
... | ... |
@@ -38,20 +42,18 @@ int t_forward_nonack( struct sip_msg* p_msg , unsigned int dest_ip_param , |
38 | 42 |
struct cell *T_source = T; |
39 | 43 |
struct lump *a,*b,*b1,*c; |
40 | 44 |
str backup_uri; |
45 |
+ int ret; |
|
46 |
+ struct socket_info* send_sock; |
|
47 |
+ union sockaddr_union to; |
|
41 | 48 |
|
42 | 49 |
|
50 |
+ /* default error value == -1; be more specific if you want to */ |
|
51 |
+ ret=-1; |
|
43 | 52 |
buf = 0; |
44 | 53 |
shbuf = 0; |
45 | 54 |
backup_uri.s = p_msg->new_uri.s; |
46 | 55 |
backup_uri.len = p_msg->new_uri.len; |
47 | 56 |
|
48 |
- /* sets as first fork the default outgoing */ |
|
49 |
- nr_forks++; |
|
50 |
- t_forks[0].ip = dest_ip_param; |
|
51 |
- t_forks[0].port = dest_port_param; |
|
52 |
- t_forks[0].uri.len = p_msg->new_uri.len; |
|
53 |
- t_forks[0].uri.s = p_msg->new_uri.s; |
|
54 |
- t_forks[0].free_flag = 0; |
|
55 | 57 |
|
56 | 58 |
|
57 | 59 |
/* are we forwarding for the first time? */ |
... | ... |
@@ -61,9 +63,32 @@ int t_forward_nonack( struct sip_msg* p_msg , unsigned int dest_ip_param , |
61 | 63 |
somewhere else */ |
62 | 64 |
LOG( L_CRIT, "ERROR: t_forward_nonack: attempt to rewrite" |
63 | 65 |
" request structures\n"); |
66 |
+ ser_error=E_BUG; |
|
64 | 67 |
return 0; |
65 | 68 |
} |
66 | 69 |
|
70 |
+ /* v6; -jiri ... copynpasted from forward_request */ |
|
71 |
+ /* if error try next ip address if possible */ |
|
72 |
+ if (p->ok==0){ |
|
73 |
+ if (p->host.h_addr_list[p->addr_idx+1]) |
|
74 |
+ p->addr_idx++; |
|
75 |
+ else p->addr_idx=0; |
|
76 |
+ p->ok=1; |
|
77 |
+ } |
|
78 |
+ hostent2su(&to, &p->host, p->addr_idx, |
|
79 |
+ (p->port)?htons(p->port):htons(SIP_PORT)); |
|
80 |
+ |
|
81 |
+ /* sets as first fork the default outgoing */ |
|
82 |
+ nr_forks++; |
|
83 |
+ /* v6; -jiri |
|
84 |
+ t_forks[0].ip = dest_ip_param; |
|
85 |
+ t_forks[0].port = dest_port_param; |
|
86 |
+ */ |
|
87 |
+ t_forks[0].to=to; |
|
88 |
+ t_forks[0].uri.len = p_msg->new_uri.len; |
|
89 |
+ t_forks[0].uri.s = p_msg->new_uri.s; |
|
90 |
+ t_forks[0].free_flag = 0; |
|
91 |
+ |
|
67 | 92 |
DBG("DEBUG: t_forward_nonack: first time forwarding\n"); |
68 | 93 |
/* special case : CANCEL */ |
69 | 94 |
if ( p_msg->REQ_METHOD==METHOD_CANCEL ) |
... | ... |
@@ -83,10 +108,14 @@ int t_forward_nonack( struct sip_msg* p_msg , unsigned int dest_ip_param , |
83 | 108 |
{ |
84 | 109 |
DBG("DEBUG: t_forward_nonack: branch %d not finalize" |
85 | 110 |
": sending CANCEL for it\n",nr_forks); |
111 |
+ /* v6; -jiri |
|
86 | 112 |
t_forks[nr_forks].ip = |
87 |
- T->T_canceled->uac[nr_forks].request.to.sin_addr.s_addr; |
|
113 |
+ T->T_canceled->uac[nr_forks].request.to.sin_addr.s_addr; |
|
88 | 114 |
t_forks[nr_forks].port = |
89 | 115 |
T->T_canceled->uac[nr_forks].request.to.sin_port; |
116 |
+ */ |
|
117 |
+ t_forks[nr_forks].to = T->T_canceled->uac[nr_forks].request.to; |
|
118 |
+ |
|
90 | 119 |
t_forks[nr_forks].uri.len = |
91 | 120 |
T->T_canceled->uac[nr_forks].uri.len; |
92 | 121 |
t_forks[nr_forks].uri.s = |
... | ... |
@@ -96,7 +125,10 @@ int t_forward_nonack( struct sip_msg* p_msg , unsigned int dest_ip_param , |
96 | 125 |
/* transaction exists, but nothing to cancel */ |
97 | 126 |
DBG("DEBUG: t_forward_nonack: branch %d finalized" |
98 | 127 |
": no CANCEL sent here\n",nr_forks); |
128 |
+ /* -v6; -jiri |
|
99 | 129 |
t_forks[nr_forks].ip = 0; |
130 |
+ */ |
|
131 |
+ t_forks[nr_forks].inactive= 1; |
|
100 | 132 |
} |
101 | 133 |
} |
102 | 134 |
#ifdef USE_SYNONIM |
... | ... |
@@ -110,14 +142,16 @@ int t_forward_nonack( struct sip_msg* p_msg , unsigned int dest_ip_param , |
110 | 142 |
}/* end special case CANCEL*/ |
111 | 143 |
|
112 | 144 |
#ifndef USE_SYNONIM |
113 |
- if ( nr_forks && add_branch_label( T_source, T->uas.request , 0 )==-1) |
|
145 |
+ branch=0; |
|
146 |
+ if ( nr_forks && add_branch_label( T_source, T->uas.request , branch )==-1) |
|
114 | 147 |
goto error; |
115 | 148 |
#endif |
116 | 149 |
|
117 | 150 |
DBG("DEBUG: t_forward_nonack: nr_forks=%d\n",nr_forks); |