... | ... |
@@ -30,4 +30,16 @@ |
30 | 30 |
|
31 | 31 |
#define MAX_URI_SIZE 1024 /* used when rewriting URIs */ |
32 | 32 |
|
33 |
+#define MY_VIA "Via: SIP/2.0/UDP " |
|
34 |
+#define MY_VIA_LEN 17 |
|
35 |
+ |
|
36 |
+ |
|
37 |
+#define MAX_PORT_LEN 7 /* ':' + max 5 letters + \0 */ |
|
38 |
+#define CRLF "\r\n" |
|
39 |
+#define CRLF_LEN 2 |
|
40 |
+ |
|
41 |
+#define RECEIVED ";received=" |
|
42 |
+#define RECEIVED_LEN 10 |
|
43 |
+ |
|
44 |
+ |
|
33 | 45 |
#endif |
... | ... |
@@ -32,6 +32,67 @@ |
32 | 32 |
#include "stats.h" |
33 | 33 |
#endif |
34 | 34 |
|
35 |
+ |
|
36 |
+static char q_inet_itoa_buf[16]; /* 123.567.901.345\0 */ |
|
37 |
+/* faster than inet_ntoa */ |
|
38 |
+__inline char* q_inet_itoa(unsigned long ip) |
|
39 |
+{ |
|
40 |
+ unsigned char* p; |
|
41 |
+ unsigned char a,b,c; /* abc.def.ghi.jkl */ |
|
42 |
+ int offset; |
|
43 |
+ int r; |
|
44 |
+ p=(unsigned char*)&ip; |
|
45 |
+ |
|
46 |
+ offset=0; |
|
47 |
+ /* unrolled loops (faster)*/ |
|
48 |
+ for(r=0;r<3;r++){ |
|
49 |
+ a=p[r]/100; |
|
50 |
+ c=p[r]%10; |
|
51 |
+ b=p[r]%100/10; |
|
52 |
+ if (a){ |
|
53 |
+ q_inet_itoa_buf[offset]=a+'0'; |
|
54 |
+ q_inet_itoa_buf[offset+1]=b+'0'; |
|
55 |
+ q_inet_itoa_buf[offset+2]=c+'0'; |
|
56 |
+ q_inet_itoa_buf[offset+3]='.'; |
|
57 |
+ offset+=4; |
|
58 |
+ }else if (b){ |
|
59 |
+ q_inet_itoa_buf[offset]=b+'0'; |
|
60 |
+ q_inet_itoa_buf[offset+1]=c+'0'; |
|
61 |
+ q_inet_itoa_buf[offset+2]='.'; |
|
62 |
+ offset+=3; |
|
63 |
+ }else{ |
|
64 |
+ q_inet_itoa_buf[offset]=c+'0'; |
|
65 |
+ q_inet_itoa_buf[offset+1]='.'; |
|
66 |
+ offset+=2; |
|
67 |
+ } |
|
68 |
+ } |
|
69 |
+ /* last number */ |
|
70 |
+ a=p[r]/100; |
|
71 |
+ c=p[r]%10; |
|
72 |
+ b=p[r]%100/10; |
|
73 |
+ if (a){ |
|
74 |
+ q_inet_itoa_buf[offset]=a+'0'; |
|
75 |
+ q_inet_itoa_buf[offset+1]=b+'0'; |
|
76 |
+ q_inet_itoa_buf[offset+2]=c+'0'; |
|
77 |
+ q_inet_itoa_buf[offset+3]=0; |
|
78 |
+ }else if (b){ |
|
79 |
+ q_inet_itoa_buf[offset]=b+'0'; |
|
80 |
+ q_inet_itoa_buf[offset+1]=c+'0'; |
|
81 |
+ q_inet_itoa_buf[offset+2]=0; |
|
82 |
+ }else{ |
|
83 |
+ q_inet_itoa_buf[offset]=c+'0'; |
|
84 |
+ q_inet_itoa_buf[offset+1]=0; |
|
85 |
+ } |
|
86 |
+ |
|
87 |
+ return q_inet_itoa_buf; |
|
88 |
+} |
|
89 |
+ |
|
90 |
+ |
|
91 |
+ |
|
92 |
+ |
|
93 |
+ |
|
94 |
+ |
|
95 |
+ |
|
35 | 96 |
/* checks if ip is in host(name) and ?host(ip)=name? |
36 | 97 |
* ip must be in network byte order! |
37 | 98 |
* resolver = DO_DNS | DO_REV_DNS; if 0 no dns check is made |
... | ... |
@@ -42,9 +103,10 @@ int check_address(unsigned long ip, char *name, int resolver) |
42 | 103 |
int i; |
43 | 104 |
|
44 | 105 |
/* maybe we are lucky and name it's an ip */ |
45 |
- if (strcmp(name, inet_ntoa( *(struct in_addr *)&ip ))==0) |
|
106 |
+ if (strcmp(name, q_inet_itoa( /* *(struct in_addr *)&*/ip ))==0) |
|
46 | 107 |
return 0; |
47 | 108 |
if (resolver&DO_DNS){ |
109 |
+ DBG("check_address: doing dns lookup\n"); |
|
48 | 110 |
/* try all names ips */ |
49 | 111 |
he=gethostbyname(name); |
50 | 112 |
for(i=0;he && he->h_addr_list[i];i++){ |
... | ... |
@@ -53,7 +115,8 @@ int check_address(unsigned long ip, char *name, int resolver) |
53 | 115 |
} |
54 | 116 |
} |
55 | 117 |
if (resolver&DO_REV_DNS){ |
56 |
- print_ip(ip); |
|
118 |
+ DBG("check_address: doing rev. dns lookup\n"); |
|
119 |
+ print_ip(ip); |
|
57 | 120 |
/* try reverse dns */ |
58 | 121 |
he=gethostbyaddr((char*)&ip, sizeof(ip), AF_INET); |
59 | 122 |
if (he && (strcmp(he->h_name, name)==0)) |
... | ... |
@@ -73,6 +136,8 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p) |
73 | 136 |
unsigned int len, new_len, via_len, received_len, uri_len; |
74 | 137 |
char* line_buf; |
75 | 138 |
char* received_buf; |
139 |
+ char* tmp; |
|
140 |
+ int tmp_len; |
|
76 | 141 |
char* new_buf; |
77 | 142 |
char* orig; |
78 | 143 |
char* buf; |
... | ... |
@@ -102,8 +167,29 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p) |
102 | 167 |
LOG(L_ERR, "ERROR: forward_request: out of memory\n"); |
103 | 168 |
goto error1; |
104 | 169 |
} |
170 |
+/* |
|
105 | 171 |
via_len=snprintf(line_buf, MAX_VIA_LINE_SIZE, "Via: SIP/2.0/UDP %s:%d\r\n", |
106 | 172 |
names[0], port_no); |
173 |
+*/ |
|
174 |
+ via_len=MY_VIA_LEN+names_len[0]; /* space included in MY_VIA*/ |
|
175 |
+ if ((via_len+port_no_str_len+CRLF_LEN)<MAX_VIA_LINE_SIZE){ |
|
176 |
+ memcpy(line_buf, MY_VIA, MY_VIA_LEN); |
|
177 |
+ memcpy(line_buf+MY_VIA_LEN, names[0], names_len[0]); |
|
178 |
+ if (port_no!=SIP_PORT){ |
|
179 |
+ memcpy(line_buf+via_len, port_no_str, port_no_str_len); |
|
180 |
+ via_len+=port_no_str_len; |
|
181 |
+ } |
|
182 |
+ memcpy(line_buf+via_len, CRLF, CRLF_LEN); |
|
183 |
+ via_len+=CRLF_LEN; |
|
184 |
+ line_buf[via_len]=0; /* null terminate the string*/ |
|
185 |
+ }else{ |
|
186 |
+ LOG(L_ERR, "forward_request: ERROR: via too long (%d)\n", |
|
187 |
+ via_len); |
|
188 |
+ goto error1; |
|
189 |
+ } |
|
190 |
+ |
|
191 |
+ |
|
192 |
+ |
|
107 | 193 |
/* check if received needs to be added */ |
108 | 194 |
if (check_address(source_ip, msg->via1.host, received_dns)!=0){ |
109 | 195 |
received_buf=malloc(sizeof(char)*MAX_RECEIVED_SIZE); |
... | ... |
@@ -111,9 +197,17 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p) |
111 | 197 |
LOG(L_ERR, "ERROR: forward_request: out of memory\n"); |
112 | 198 |
goto error1; |
113 | 199 |
} |
200 |
+ /* |
|
114 | 201 |
received_len=snprintf(received_buf, MAX_RECEIVED_SIZE, |
115 | 202 |
";received=%s", |
116 | 203 |
inet_ntoa(*(struct in_addr *)&source_ip)); |
204 |
+ */ |
|
205 |
+ memcpy(received_buf, RECEIVED, RECEIVED_LEN); |
|
206 |
+ tmp=q_inet_itoa( /* *(struct in_addr *)& */source_ip); |
|
207 |
+ tmp_len=strlen(tmp); |
|
208 |
+ received_len=RECEIVED_LEN+tmp_len; |
|
209 |
+ memcpy(received_buf+RECEIVED_LEN, tmp, tmp_len); |
|
210 |
+ received_buf[received_len]=0; /*null terminate it */ |
|
117 | 211 |
} |
118 | 212 |
|
119 | 213 |
/* add via header to the list */ |
... | ... |
@@ -16,8 +16,11 @@ |
16 | 16 |
|
17 | 17 |
extern char * cfg_file; |
18 | 18 |
extern unsigned short port_no; |
19 |
+extern char port_no_str[]; |
|
20 |
+extern int port_no_str_len; |
|
19 | 21 |
extern unsigned int maxbuffer; |
20 | 22 |
extern char * names[]; |
23 |
+extern int names_len[]; |
|
21 | 24 |
extern unsigned long addresses[]; |
22 | 25 |
extern int addresses_no; |
23 | 26 |
extern int children_no; |
... | ... |
@@ -34,7 +34,7 @@ |
34 | 34 |
|
35 | 35 |
|
36 | 36 |
static char id[]="@(#) $Id$"; |
37 |
-static char version[]="ser 0.8.3.1"; |
|
37 |
+static char version[]="ser 0.8.3.2"; |
|
38 | 38 |
static char flags[]="NOCR:" |
39 | 39 |
#ifdef NOCR |
40 | 40 |
"On" |
... | ... |
@@ -98,6 +98,8 @@ void receive_stdin_loop() |
98 | 98 |
|
99 | 99 |
char* cfg_file = 0; |
100 | 100 |
unsigned short port_no = 0; /* port on which we listen */ |
101 |
+char port_no_str[MAX_PORT_LEN]; |
|
102 |
+int port_no_str_len=0; |
|
101 | 103 |
unsigned int maxbuffer = 128*1024; /* maximum buffer size we do not want to exceed |
102 | 104 |
durig the auto-probing procedure; may be |
103 | 105 |
re-configured */ |
... | ... |
@@ -110,6 +112,7 @@ int received_dns = 0; /* use dns and/or rdns or to see if we need to |
110 | 112 |
add a ;received=x.x.x.x to via: */ |
111 | 113 |
|
112 | 114 |
char* names[MAX_LISTEN]; /* our names */ |
115 |
+int names_len[MAX_LISTEN]; /* lengths of the names*/ |
|
113 | 116 |
unsigned long addresses[MAX_LISTEN]; /* our ips */ |
114 | 117 |
int addresses_no=0; /* number of names/ips */ |
115 | 118 |
|
... | ... |
@@ -383,6 +386,18 @@ int main(int argc, char** argv) |
383 | 386 |
|
384 | 387 |
/* fix parameters */ |
385 | 388 |
if (port_no<=0) port_no=SIP_PORT; |
389 |
+ port_no_str_len=snprintf(port_no_str, MAX_PORT_LEN, ":%d", |
|
390 |
+ (unsigned short) port_no); |
|
391 |
+ if (port_no_str_len<0){ |
|
392 |
+ fprintf(stderr, "ERROR: bad port number: %d\n", port_no); |
|
393 |
+ goto error; |
|
394 |
+ } |
|
395 |
+ /* on some system snprintf return really strange things if it does not have |
|
396 |
+ * enough space */ |
|
397 |
+ port_no_str_len= |
|
398 |
+ (port_no_str_len<MAX_PORT_LEN)?port_no_str_len:MAX_PORT_LEN; |
|
399 |
+ |
|
400 |
+ |
|
386 | 401 |
if (children_no<=0) children_no=CHILD_NO; |
387 | 402 |
if (addresses_no==0) { |
388 | 403 |
/* get our address, only the first one */ |
... | ... |
@@ -400,6 +415,11 @@ int main(int argc, char** argv) |
400 | 415 |
addresses_no++; |
401 | 416 |
} |
402 | 417 |
|
418 |
+ /*get name lens*/ |
|
419 |
+ for(r=0; r<addresses_no; r++){ |
|
420 |
+ names_len[r]=strlen(names[r]); |
|
421 |
+ } |
|
422 |
+ |
|
403 | 423 |
#ifdef STATS |
404 | 424 |
/* jku: initialize statistic */ |
405 | 425 |
memset(&stats,0,sizeof(struct stats_s)); |
... | ... |
@@ -1,4 +1,4 @@ |
1 |
-debug=9 # for speed |
|
1 |
+debug=0 # for speed |
|
2 | 2 |
check_via=0 |
3 | 3 |
dns=off |
4 | 4 |
rev_dns=off |
... | ... |
@@ -8,10 +8,6 @@ children=8 |
8 | 8 |
|
9 | 9 |
route{ |
10 | 10 |
|
11 |
- if ( method=~'^INV' && uri=~'iptel\.org' ){ |
|
12 |
- forward(127.0.0.1, 5060); |
|
13 |
- drop; |
|
14 |
- }; |
|
15 |
- log("no rule for this packet => dropping\n"); |
|
11 |
+forward(127.0.0.1,5061); |
|
16 | 12 |
} |
17 | 13 |
|