Browse code

- made ipv4<->ipv6 possible - added different port numbers (eg. ser -l foo -p 1234 -l bar -p 4321 ) - small signal fixes (sigterm to evrybody on exit, exit if 1 child dies a.s.o)

Andrei Pelinescu-Onciul authored on 26/05/2002 21:38:02
Showing 15 changed files
... ...
@@ -8,7 +8,7 @@
8 8
 VERSION = 0
9 9
 PATCHLEVEL = 8
10 10
 SUBLEVEL = 8
11
-EXTRAVERSION = -1-ipv6
11
+EXTRAVERSION = -2-ipv6
12 12
 
13 13
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
14 14
 OS = $(shell uname -s)
... ...
@@ -38,6 +38,7 @@ int do_action(struct action* a, struct sip_msg* msg)
38 38
 	int ret;
39 39
 	int v;
40 40
 	union sockaddr_union* to;
41
+	struct socket_info* send_sock;
41 42
 	struct proxy_l* p;
42 43
 	char* tmp;
43 44
 	char *new_uri, *end, *crt;
... ...
@@ -144,8 +145,13 @@ int do_action(struct action* a, struct sip_msg* msg)
144 144
 			if (ret==0){
145 145
 				p->tx++;
146 146
 				p->tx_bytes+=msg->len;
147
-				ret=udp_send(msg->orig, msg->len, to,
148
-								sizeof(union sockaddr_union));
147
+				send_sock=get_send_socket(to);
148
+				if (send_sock!=0){
149
+					ret=udp_send(send_sock, msg->orig, msg->len, to,
150
+									sizeof(union sockaddr_union));
151
+				}else{
152
+					ret=-1;
153
+				}
149 154
 			}
150 155
 			free(to);
151 156
 			if (ret<0){
... ...
@@ -25,7 +25,7 @@
25 25
 	
26 26
 	static int comment_nest=0;
27 27
 	static int state=0;
28
-	static char* str=0;
28
+	static char* tstr=0;
29 29
 	int line=1;
30 30
 	int column=1;
31 31
 	int startcolumn=1;
... ...
@@ -219,29 +219,29 @@ EAT_ABLE	[\ \t\b\r]
219 219
 
220 220
 <STRING1>{QUOTES} { count(); state=INITIAL_S; BEGIN(INITIAL); 
221 221
 						yytext[yyleng-1]=0; yyleng--;
222
-						addstr(yytext, &str);
223
-						yylval.strval=str; str=0;
222
+						addstr(yytext, &tstr);
223
+						yylval.strval=tstr; tstr=0;
224 224
 						return STRING;
225 225
 					}
226 226
 <STRING2>{TICK}  { count(); state=INITIAL_S; BEGIN(INITIAL); 
227 227
 						yytext[yyleng-1]=0; yyleng--;
228
-						addstr(yytext, &str);
229
-						yylval.strval=str;
230
-						str=0;
228
+						addstr(yytext, &tstr);
229
+						yylval.strval=tstr;
230
+						tstr=0;
231 231
 						return STRING;
232 232
 					}
233 233
 <STRING2>.|{EAT_ABLE}|{CR}	{ yymore(); }
234 234
 
235 235
 <STRING1>\\n		{ count(); yytext[yyleng-2]='\n';yytext[yyleng-1]=0; 
236
-						yyleng--; addstr(yytext, &str); }
236
+						yyleng--; addstr(yytext, &tstr); }
237 237
 <STRING1>\\r		{ count(); yytext[yyleng-2]='\r';yytext[yyleng-1]=0; 
238
-						yyleng--; addstr(yytext, &str); }
238
+						yyleng--; addstr(yytext, &tstr); }
239 239
 <STRING1>\\a		{ count(); yytext[yyleng-2]='\a';yytext[yyleng-1]=0; 
240
-						yyleng--; addstr(yytext, &str); }
240
+						yyleng--; addstr(yytext, &tstr); }
241 241
 <STRING1>\\t		{ count(); yytext[yyleng-2]='\t';yytext[yyleng-1]=0; 
242
-						yyleng--; addstr(yytext, &str); }
242
+						yyleng--; addstr(yytext, &tstr); }
243 243
 <STRING1>\\\\		{ count(); yytext[yyleng-2]='\\';yytext[yyleng-1]=0; 
244
-						yyleng--; addstr(yytext, &str); } 
244
+						yyleng--; addstr(yytext, &tstr); } 
245 245
 <STRING1>.|{EAT_ABLE}|{CR}	{ yymore(); }
246 246
 
247 247
 
... ...
@@ -257,8 +257,8 @@ EAT_ABLE	[\ \t\b\r]
257 257
 
258 258
 <INITIAL>{COM_LINE}.*{CR}	{ count(); } 
259 259
 
260
-<INITIAL>{ID}			{ count(); addstr(yytext, &str);
261
-						  yylval.strval=str; str=0; return ID; }
260
+<INITIAL>{ID}			{ count(); addstr(yytext, &tstr);
261
+						  yylval.strval=tstr; tstr=0; return ID; }
262 262
 
263 263
 
264 264
 <<EOF>>							{
... ...
@@ -266,7 +266,7 @@ EAT_ABLE	[\ \t\b\r]
266 266
 										case STRING_S: 
267 267
 											LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF in"
268 268
 														" unclosed string\n");
269
-											if (str) {free(str); str=0;}
269
+											if (tstr) {free(tstr); tstr=0;}
270 270
 											break;
271 271
 										case COMMENT_S:
272 272
 											LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF:"
... ...
@@ -164,7 +164,10 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
164 164
 		| DNS EQUAL error { yyerror("boolean value expected"); }
165 165
 		| REV_DNS EQUAL NUMBER { received_dns|= ($3)?DO_REV_DNS:0; }
166 166
 		| REV_DNS EQUAL error { yyerror("boolean value expected"); }
167
-		| PORT EQUAL NUMBER   { port_no=$3; }
167
+		| PORT EQUAL NUMBER   { port_no=$3; 
168
+								if (sock_no>0) 
169
+									sock_info[sock_no-1].port_no=port_no;
170
+							  }
168 171
 		| STAT EQUAL STRING {
169 172
 					#ifdef STATS
170 173
 							stat_file=$3;
... ...
@@ -180,7 +183,7 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
180 180
 		| LOOP_CHECKS EQUAL NUMBER { loop_checks=$3; }
181 181
 		| LOOP_CHECKS EQUAL error { yyerror("boolean value expected"); }
182 182
 		| LISTEN EQUAL ip  {
183
-								if (addresses_no < MAX_LISTEN){
183
+								if (sock_no< MAX_LISTEN){
184 184
 									tmp=ip_addr2a($3);
185 185
 								/*	tmp=inet_ntoa(*(struct in_addr*)&$3);*/
186 186
 									if (tmp==0){
... ...
@@ -188,15 +191,19 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
188 188
 											" bad ip address: %s\n",
189 189
 											strerror(errno));
190 190
 									}else{
191
-										names[addresses_no]=
191
+										sock_info[sock_no].name.s=
192 192
 												(char*)malloc(strlen(tmp)+1);
193
-										if (names[addresses_no]==0){
193
+										if (sock_info[sock_no].name.s==0){
194 194
 											LOG(L_CRIT, "ERROR: cfg. parser: "
195 195
 														"out of memory.\n");
196 196
 										}else{
197
-											strncpy(names[addresses_no], tmp,
198
-													strlen(tmp)+1);
199
-											addresses_no++;
197
+											strncpy(sock_info[sock_no].name.s,
198
+													tmp, strlen(tmp)+1);
199
+											sock_info[sock_no].name.len=
200
+													strlen(tmp);
201
+											sock_info[sock_no].port_no=
202
+													port_no;
203
+											sock_no++;
200 204
 										}
201 205
 									}
202 206
 								}else{
... ...
@@ -206,16 +213,18 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
206 206
 								}
207 207
 							  }
208 208
 		| LISTEN EQUAL ID	 {
209
-								if (addresses_no < MAX_LISTEN){
210
-									names[addresses_no]=
209
+								if (sock_no < MAX_LISTEN){
210
+									sock_info[sock_no].name.s=
211 211
 												(char*)malloc(strlen($3)+1);
212
-									if (names[addresses_no]==0){
212
+									if (sock_info[sock_no].name.s==0){
213 213
 										LOG(L_CRIT, "ERROR: cfg. parser:"
214 214
 														" out of memory.\n");
215 215
 									}else{
216
-										strncpy(names[addresses_no], $3,
216
+										strncpy(sock_info[sock_no].name.s, $3,
217 217
 													strlen($3)+1);
218
-										addresses_no++;
218
+										sock_info[sock_no].name.len=strlen($3);
219
+										sock_info[sock_no].port_no= port_no;
220
+										sock_no++;
219 221
 									}
220 222
 								}else{
221 223
 									LOG(L_CRIT, "ERROR: cfg. parser: "
... ...
@@ -224,16 +233,18 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
224 224
 								}
225 225
 							  }
226 226
 		| LISTEN EQUAL STRING {
227
-								if (addresses_no < MAX_LISTEN){
228
-									names[addresses_no]=
227
+								if (sock_no < MAX_LISTEN){
228
+									sock_info[sock_no].name.s=
229 229
 										(char*)malloc(strlen($3)+1);
230
-									if (names[addresses_no]==0){
230
+									if (sock_info[sock_no].name.s==0){
231 231
 										LOG(L_CRIT, "ERROR: cfg. parser:"
232 232
 													" out of memory.\n");
233 233
 									}else{
234
-										strncpy(names[addresses_no], $3,
234
+										strncpy(sock_info[sock_no].name.s, $3,
235 235
 												strlen($3)+1);
236
-										addresses_no++;
236
+										sock_info[sock_no].name.len=strlen($3);
237
+										sock_info[sock_no].port_no=port_no;
238
+										sock_no++;
237 239
 									}
238 240
 								}else{
239 241
 									LOG(L_CRIT, "ERROR: cfg. parser: "
... ...
@@ -64,7 +64,6 @@
64 64
 #define SHM_MEM_SIZE 128 
65 65
 
66 66
 #define TIMER_TICK 1
67
-#define LONG_SLEEP	3600
68 67
 
69 68
 /* dimensioning buckets in q_malloc */
70 69
 /* size of the size2bucket table; everything beyond that asks for
... ...
@@ -34,29 +34,50 @@
34 34
 
35 35
 
36 36
 
37
+/* returns a socket_info pointer to the sending socket or 0 on error
38
+ * params: destination socke_union pointer
39
+ */
40
+struct socket_info* get_send_socket(union sockaddr_union* to)
41
+{
42
+	struct socket_info* send_sock;
43
+	
44
+	send_sock=0;
45
+	/* check if we need to change the socket (different address families -
46
+	 * eg: ipv4 -> ipv6 or ipv6 -> ipv4) */
47
+	if (to->s.sa_family!=bind_address->address.af){
48
+		switch(to->s.sa_family){
49
+			case AF_INET:	send_sock=sendipv4;
50
+							break;
51
+#ifdef USE_IPV6
52
+			case AF_INET6:	send_sock=sendipv6;
53
+							break;
54
+#endif
55
+			default:		LOG(L_ERR, "get_send_socket: BUG: don't know how"
56
+									" to forward to af %d\n", to->s.sa_family);
57
+		}
58
+	}else send_sock=bind_address;
59
+	return send_sock;
60
+}
61
+
62
+
63
+
37 64
 int forward_request( struct sip_msg* msg, struct proxy_l * p)
38 65
 {
39 66
 	unsigned int len;
40 67
 	char* buf;
41 68
 	union sockaddr_union* to;
42
-
69
+	struct socket_info* send_sock;
70
+	
43 71
 	to=0;
44
-	buf = build_req_buf_from_sip_req( msg, &len);
45
-	if (!buf){
46
-		LOG(L_ERR, "ERROR: forward_reply: building failed\n");
47
-		goto error;
48
-	}
49
-
72
+	buf=0;
73
+	
50 74
 	to=(union sockaddr_union*)malloc(sizeof(union sockaddr_union));
51 75
 	if (to==0){
52 76
 		LOG(L_ERR, "ERROR: forward_request: out of memory\n");
53 77
 		goto error;
54 78
 	}
55
-
56
-	 /* send it! */
57
-	DBG("Sending:\n%s.\n", buf);
58
-	DBG("orig. len=%d, new_len=%d\n", msg->len, len );
59
-
79
+	
80
+	
60 81
 	/* if error try next ip address if possible */
61 82
 	if (p->ok==0){
62 83
 		if (p->host.h_addr_list[p->addr_idx+1])
... ...
@@ -64,13 +85,31 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
64 64
 		else p->addr_idx=0;
65 65
 		p->ok=1;
66 66
 	}
67
-
67
+	
68 68
 	hostent2su(to, &p->host, p->addr_idx, 
69 69
 				(p->port)?htons(p->port):htons(SIP_PORT));
70 70
 	p->tx++;
71 71
 	p->tx_bytes+=len;
72
+	
72 73
 
73
-	if (udp_send( buf, len,  to, sizeof(union sockaddr_union))==-1){
74
+	send_sock=get_send_socket(to);
75
+	if (send_sock==0){
76
+		LOG(L_ERR, "forward_req: ERROR: cannot forward to af %d "
77
+				"no coresponding listening socket\n", to->s.sa_family);
78
+		goto error;
79
+	}
80
+	
81
+	buf = build_req_buf_from_sip_req( msg, &len, send_sock);
82
+	if (!buf){
83
+		LOG(L_ERR, "ERROR: forward_reply: building failed\n");
84
+		goto error;
85
+	}
86
+	 /* send it! */
87
+	DBG("Sending:\n%s.\n", buf);
88
+	DBG("orig. len=%d, new_len=%d\n", msg->len, len );
89
+	
90
+	if (udp_send( send_sock, buf, len,  to, 
91
+							sizeof(union sockaddr_union))==-1){
74 92
 			p->errors++;
75 93
 			p->ok=0;
76 94
 			STATS_TX_DROPS;
... ...
@@ -145,6 +184,7 @@ int forward_reply(struct sip_msg* msg)
145 145
 	int  r;
146 146
 	char* new_buf;
147 147
 	union sockaddr_union* to;
148
+	struct socket_info* send_sock;
148 149
 	unsigned int new_len;
149 150
 	struct sr_module *mod;
150 151
 	
... ...
@@ -152,11 +192,14 @@ int forward_reply(struct sip_msg* msg)
152 152
 	new_buf=0;
153 153
 	/*check if first via host = us */
154 154
 	if (check_via){
155
-		for (r=0; r<addresses_no; r++)
156
-			if(strcmp(msg->via1->host.s, names[r])==0) break;
157
-		if (r==addresses_no){
155
+		for (r=0; r<sock_no; r++)
156
+			if ( (msg->via1->host.len==sock_info[r].name.len) && 
157
+					(memcmp(msg->via1->host.s, sock_info[r].name.s, 
158
+										sock_info[r].name.len)==0) )
159
+				break;
160
+		if (r==sock_no){
158 161
 			LOG(L_NOTICE, "ERROR: forward_reply: host in first via!=me :"
159
-					" %s\n", msg->via1->host.s);
162
+					" %.*s\n", msg->via1->host.len, msg->via1->host.s);
160 163
 			/* send error msg back? */
161 164
 			goto error;
162 165
 		}
... ...
@@ -192,8 +235,13 @@ int forward_reply(struct sip_msg* msg)
192 192
 	}
193 193
 
194 194
 	if (update_sock_struct_from_via( to, msg->via2 )==-1) goto error;
195
+	send_sock=get_send_socket(to);
196
+	if (send_sock==0){
197
+		LOG(L_ERR, "forward_reply: ERROR: no sending socket found\n");
198
+		goto error;
199
+	}
195 200
 
196
-	if (udp_send(new_buf,new_len,  to,
201
+	if (udp_send(send_sock, new_buf,new_len,  to,
197 202
 				sizeof(union sockaddr_union))==-1)
198 203
 	{
199 204
 		STATS_TX_DROPS;
... ...
@@ -9,8 +9,10 @@
9 9
 #include "parser/msg_parser.h"
10 10
 #include "route.h"
11 11
 #include "proxy.h"
12
+#include "ip_addr.h"
12 13
 
13 14
 
15
+struct socket_info* get_send_socket(union sockaddr_union* su);
14 16
 int forward_request( struct sip_msg* msg,  struct proxy_l* p);
15 17
 int update_sock_struct_from_via( union sockaddr_union* to,
16 18
 								struct via_body* via );
... ...
@@ -11,23 +11,35 @@
11 11
 
12 12
 #include "types.h"
13 13
 #include "ip_addr.h"
14
+#include "str.h"
14 15
 
15 16
 #define NO_DNS     0
16 17
 #define DO_DNS     1
17 18
 #define DO_REV_DNS 2
18 19
 
19 20
 
21
+
20 22
 extern char * cfg_file;
21 23
 extern char *stat_file;
24
+extern struct socket_info sock_info[]; /* all addresses we listen/send from*/
25
+extern int sock_no; /* number of addresses/open sockets*/
22 26
 extern unsigned short port_no;
27
+/*
23 28
 extern char port_no_str[];
24 29
 extern int port_no_str_len;
25
-extern unsigned int maxbuffer;
30
+*/
31
+/*
26 32
 extern char * names[];
27 33
 extern int names_len[];
28 34
 extern struct ip_addr addresses[];
29 35
 extern int addresses_no;
30
-extern struct ip_addr* bind_address;
36
+*/
37
+extern struct socket_info* bind_address; /* pointer to the crt. proc. listening address */
38
+extern int bind_idx; /* same as above but index in the bound[] array */
39
+extern struct socket_info* sendipv4; /* ipv4 socket to use when msg. comes from ipv6*/
40
+extern struct socket_info* sendipv6; /* same as above for ipv6 */
41
+
42
+extern unsigned int maxbuffer;
31 43
 extern int children_no;
32 44
 extern int dont_fork;
33 45
 extern int check_via;
... ...
@@ -9,6 +9,7 @@
9 9
 #include <string.h>
10 10
 #include <netinet/in.h>
11 11
 #include <netdb.h>
12
+#include "str.h"
12 13
 
13 14
 #ifdef USE_IPV6
14 15
 	#ifdef FreeBSD			/* freebsd is brain damaged and needs a different
... ...
@@ -49,6 +50,15 @@ union sockaddr_union{
49 49
 };
50 50
 
51 51
 
52
+struct socket_info{
53
+	int socket;
54
+	str name; /* name - eg.: foo.bar or 10.0.0.1 */
55
+	struct ip_addr address; /* ip address */
56
+	str address_str;        /* ip address converted to string -- optimization*/
57
+	unsigned short port_no;  /* port number */
58
+	str port_no_str; /* port number converted to string -- optimization*/
59
+};
60
+
52 61
 
53 62
 
54 63
 /* inits an ip_addr with the addr. info from a hostent structure
... ...
@@ -215,6 +225,7 @@ static inline char* ip_addr2a(struct ip_addr* ip)
215 215
 	register unsigned char a,b,c;
216 216
 #ifdef USE_IPV6
217 217
 	register unsigned char d;
218
+	register unsigned short hex4;
218 219
 #endif
219 220
 	int r;
220 221
 	#define HEXDIG(x) (((x)>=10)?(x)-10+'A':(x)+'0')
... ...
@@ -225,10 +236,11 @@ static inline char* ip_addr2a(struct ip_addr* ip)
225 225
 	#ifdef USE_IPV6
226 226
 		case AF_INET6:
227 227
 			for(r=0;r<7;r++){
228
-				a=ip->u.addr16[r]>>12;
229
-				b=(ip->u.addr16[r]>>8)&0xf;
230
-				c=(ip->u.addr16[r]>>4)&0xf;
231
-				d=ip->u.addr16[r]&0xf;
228
+				hex4=ntohs(ip->u.addr16[r]);
229
+				a=hex4>>12;
230
+				b=(hex4>>8)&0xf;
231
+				c=(hex4>>4)&0xf;
232
+				d=hex4&0xf;
232 233
 				if (a){
233 234
 					buff[offset]=HEXDIG(a);
234 235
 					buff[offset+1]=HEXDIG(b);
... ...
@@ -254,10 +266,11 @@ static inline char* ip_addr2a(struct ip_addr* ip)
254 254
 				}
255 255
 			}
256 256
 			/* last int16*/
257
-			a=ip->u.addr16[r]>>12;
258
-			b=(ip->u.addr16[r]>>8)&0xf;
259
-			c=(ip->u.addr16[r]>>4)&0xf;
260
-			d=ip->u.addr16[r]&0xf;
257
+			hex4=ntohs(ip->u.addr16[r]);
258
+			a=hex4>>12;
259
+			b=(hex4>>8)&0xf;
260
+			c=(hex4>>4)&0xf;
261
+			d=hex4&0xf;
261 262
 			if (a){
262 263
 				buff[offset]=HEXDIG(a);
263 264
 				buff[offset+1]=HEXDIG(b);
... ...
@@ -122,11 +122,13 @@ static char flags[]=
122 122
 ;
123 123
 
124 124
 static char help_msg[]= "\
125
-Usage: " NAME " -l address [-l address] [options]\n\
125
+Usage: " NAME " -l address [-p port] [-l address [-p port]...] [options]\n\
126 126
 Options:\n\
127 127
     -c           Perform loop checks and compute branches\n\
128 128
     -f file      Configuration file (default " CFG_FILE ")\n\
129 129
     -p port      Listen on the specified port (default: 5060)\n\
130
+                 applies to the last address in -l and to all \n\
131
+                 following that do not have a corespponding -p\n\
130 132
     -l address   Listen on the specified address (multiple -l mean\n\
131 133
                  listening on more addresses). The default behaviour\n\
132 134
                  is to listen on the addresses returned by uname(2)\n\
... ...
@@ -195,9 +197,6 @@ void receive_stdin_loop()
195 195
 /* global vars */
196 196
 
197 197
 char* cfg_file = 0;
198
-unsigned short port_no = 0; /* port on which we listen */
199
-char port_no_str[MAX_PORT_LEN];
200
-int port_no_str_len=0;
201 198
 unsigned int maxbuffer = MAX_RECV_BUFFER_SIZE; /* maximum buffer size we do
202 199
 												  not want to exceed durig the
203 200
 												  auto-probing procedure; may 
... ...
@@ -217,11 +216,20 @@ char* chroot_dir = 0;
217 217
 int uid = 0;
218 218
 int gid = 0;
219 219
 
220
+#if 0
220 221
 char* names[MAX_LISTEN];              /* our names */
221 222
 int names_len[MAX_LISTEN];            /* lengths of the names*/
222 223
 struct ip_addr addresses[MAX_LISTEN]; /* our ips */
223 224
 int addresses_no=0;                   /* number of names/ips */
224
-struct ip_addr* bind_address;        /* listen address of the crt. process */
225
+#endif
226
+struct socket_info sock_info[MAX_LISTEN]; /* all addresses we listen/send from*/
227
+int sock_no=0; /* number of addresses/open sockets*/
228
+struct socket_info* bind_address; /* pointer to the crt. proc. listening address */
229
+int bind_idx; /* same as above but index in the bound[] array */
230
+struct socket_info* sendipv4; /* ipv4 socket to use when msg. comes from ipv6*/
231
+struct socket_info* sendipv6; /* same as above for ipv6 */
232
+
233
+unsigned short port_no=0; /* default port*/
225 234
 
226 235
 /* ipc related globals */
227 236
 int process_no = 0;
... ...
@@ -246,7 +254,6 @@ extern int yyparse();
246 246
 static int is_main=0; /* flag = is this the  "main" process? */
247 247
 
248 248
 char* pid_file = 0; /* filename as asked by use */
249
-char *pid_fn = 0; /* and with port number appended */
250 249
 
251 250
 /* daemon init, return 0 on success, -1 on error */
252 251
 int daemonize(char*  name)
... ...
@@ -255,7 +262,6 @@ int daemonize(char*  name)
255 255
 	pid_t pid;
256 256
 	int r, p;
257 257
 
258
-	int pid_fn_len;
259 258
 
260 259
 	p=-1;
261 260
 
... ...
@@ -288,8 +294,7 @@ int daemonize(char*  name)
288 288
 	if ((pid=fork())<0){
289 289
 		LOG(L_CRIT, "Cannot fork:%s\n", strerror(errno));
290 290
 		goto error;
291
-	}
292
-	if (pid!=0){
291
+	}else if (pid!=0){
293 292
 		/* parent process => exit*/
294 293
 		exit(0);
295 294
 	}
... ...
@@ -301,49 +306,34 @@ int daemonize(char*  name)
301 301
 	if ((pid=fork())<0){
302 302
 		LOG(L_CRIT, "Cannot  fork:%s\n", strerror(errno));
303 303
 		goto error;
304
-	}
305
-	if (pid!=0){
304
+	}else if (pid!=0){
306 305
 		/*parent process => exit */
307 306
 		exit(0);
308 307
 	}
309 308
 
310 309
 	/* added by noh: create a pid file for the main process */
311 310
 	if (pid_file!=0){
312
-
313
-		/* added port number; -jiri */
314
-		pid_fn_len = strlen(pid_file) + 5 /* long port number */ 
315
-			+ 1 /* dot */ + 1 /* ZT */ ;
316
-		pid_fn = malloc( pid_fn_len );
317
-		if (!pid_fn) {
318
-			LOG(L_ERR, "ERROR: There is really no memory for ser\n");
319
-			goto error;
320
-		}
321
-		if (snprintf(pid_fn, pid_fn_len, "%s.%d", pid_file, port_no )==-1) {
322
-			LOG(L_ERR, "ERROR: pidfile printig failed -- perhaps too high port?\n");
323
-			goto error;
324
-		}
325 311
 		
326
-			
327
-		if ((pid_stream=fopen(pid_fn, "r"))!=NULL){
312
+		if ((pid_stream=fopen(pid_file, "r"))!=NULL){
328 313
 			fscanf(pid_stream, "%d", &p);
329 314
 			fclose(pid_stream);
330 315
 			if (p==-1){
331 316
 				LOG(L_CRIT, "pid file %s exists, but doesn't contain a valid"
332
-					" pid number\n", pid_fn);
317
+					" pid number\n", pid_file);
333 318
 				goto error;
334 319
 			}
335 320
 			if (kill((pid_t)p, 0)==0 || errno==EPERM){
336 321
 				LOG(L_CRIT, "running process found in the pid file %s\n",
337
-					pid_fn);
322
+					pid_file);
338 323
 				goto error;
339 324
 			}else{
340 325
 				LOG(L_WARN, "pid file contains old pid, replacing pid\n");
341 326
 			}
342 327
 		}
343 328
 		pid=getpid();
344
-		if ((pid_stream=fopen(pid_fn, "w"))==NULL){
329
+		if ((pid_stream=fopen(pid_file, "w"))==NULL){
345 330
 			LOG(L_WARN, "unable to create pid file %s: %s\n", 
346
-				pid_fn, strerror(errno));
331
+				pid_file, strerror(errno));
347 332
 			goto error;
348 333
 		}else{
349 334
 			fprintf(pid_stream, "%i\n", (int)pid);
... ...
@@ -378,14 +368,19 @@ int main_loop()
378 378
 #ifdef STATS
379 379
 		setstats( 0 );
380 380
 #endif
381
-		/* only one address */
382
-		if (udp_init(&addresses[0],port_no)==-1) goto error;
381
+		/* only one address, we ignore all the others */
382
+		if (udp_init(&sock_info[0])==-1) goto error;
383
+		bind_address=&sock_info[0];
384
+		bind_idx=0;
385
+		if (sock_no>1){
386
+			LOG(L_WARN, "WARNING: using only the first listen address (no fork)\n");
387
+		}
383 388
 
384 389
 		/* we need another process to act as the timer*/
385 390
 		if (timer_list){
386 391
 				process_no++;
387 392
 				if ((pid=fork())<0){
388
-					LOG(L_CRIT,  "ERRROR: main_loop: Cannot fork\n");
393
+					LOG(L_CRIT,  "ERROR: main_loop: Cannot fork\n");
389 394
 					goto error;
390 395
 				}
391 396
 				
... ...
@@ -418,17 +413,28 @@ int main_loop()
418 418
 		
419 419
 		return udp_rcv_loop();
420 420
 	}else{
421
-		for(r=0;r<addresses_no;r++){
421
+		for(r=0;r<sock_no;r++){
422 422
 			/* create the listening socket (for each address)*/
423
-			if (udp_init(&addresses[r], port_no)==-1) goto error;
423
+			if (udp_init(&sock_info[r])==-1) goto error;
424
+			/* get first ipv4/ipv6 socket*/
425
+			if ((sendipv4==0)&&(sock_info[r].address.af==AF_INET))
426
+				sendipv4=&sock_info[r];
427
+	#ifdef USE_IPV6
428
+			if((sendipv6==0)&&(sock_info[r].address.af==AF_INET6))
429
+				sendipv6=&sock_info[r];
430
+	#endif
431
+			/* all procs should have access to all the sockets (for sending)
432
+			 * so we open all first*/
433
+		}
434
+		for(r=0; r<sock_no;r++){
424 435
 			for(i=0;i<children_no;i++){
425 436
 				if ((pid=fork())<0){
426 437
 					LOG(L_CRIT,  "main_loop: Cannot fork\n");
427 438
 					goto error;
428
-				}
429
-				if (pid==0){
439
+				}else if (pid==0){
430 440
 					     /* child */
431
-
441
+					bind_address=&sock_info[r]; /* shortcut */
442
+					bind_idx=r;
432 443
 					if (init_child(i) < 0) {
433 444
 						LOG(L_ERR, "init_child failed\n");
434 445
 						goto error;
... ...
@@ -452,6 +458,9 @@ int main_loop()
452 452
 	pids[process_no]=getpid();
453 453
 	process_bit = 0;
454 454
 	is_main=1;
455
+	bind_address=&sock_info[0]; /* main proc -> it shoudln't send anything, if it does */
456
+	bind_idx=0;					/*   it will use the first address */
457
+
455 458
 	if (timer_list){
456 459
 		for(;;){
457 460
 			/* debug:  instead of doing something usefull */
... ...
@@ -461,7 +470,7 @@ int main_loop()
461 461
 			timer_ticker();
462 462
 		}
463 463
 	}else{
464
-		for(;;) sleep(LONG_SLEEP);
464
+		for(;;) pause(); 
465 465
 	}
466 466
 	
467 467
 	/*return 0; */
... ...
@@ -474,8 +483,7 @@ int main_loop()
474 474
 /* added by jku; allows for regular exit on a specific signal;
475 475
    good for profiling which only works if exited regularly and
476 476
    not by default signal handlers
477
-*/	
478
-
477
+*/
479 478
 static void sig_usr(int signo)
480 479
 {
481 480
 	pid_t	chld;
... ...
@@ -508,6 +516,8 @@ static void sig_usr(int signo)
508 508
 		}
509 509
 #endif
510 510
 		dprint("Thank you for flying " NAME "\n");
511
+		/* kill children also*/
512
+		kill(0, SIGTERM);
511 513
 		exit(0);
512 514
 	} else if (signo==SIGTERM) { /* exit gracefully as daemon */
513 515
 		DPrint("TERM received, program terminates\n");
... ...
@@ -515,11 +525,11 @@ static void sig_usr(int signo)
515 515
 #ifdef STATS
516 516
 			dump_all_statistic();
517 517
 #endif
518
-			if (pid_fn) {
519
-				unlink(pid_fn);
520
-				free(pid_fn);
518
+			if (pid_file) {
519
+				unlink(pid_file);
521 520
 			}
522 521
 		}
522
+		kill(0, SIGTERM);
523 523
 		exit(0);
524 524
 	} else if (signo==SIGUSR1) { /* statistic */
525 525
 #ifdef STATS
... ...
@@ -549,6 +559,9 @@ static void sig_usr(int signo)
549 549
 				LOG(L_INFO, "child process %d stopped by a signal %d\n",
550 550
 					chld, WSTOPSIG(chld_status));
551 551
 		}
552
+		/* exit */
553
+		kill(0, SIGTERM);
554
+		exit(0);
552 555
 	}
553 556
 }
554 557
 
... ...
@@ -564,6 +577,8 @@ int main(int argc, char** argv)
564 564
 	char *tmp;
565 565
 	struct utsname myname;
566 566
 	char *options;
567
+	char port_no_str[MAX_PORT_LEN];
568
+	int port_no_str_len=0;
567 569
 
568 570
 	/* added by jku: add exit handler */
569 571
 	if (signal(SIGINT, sig_usr) == SIG_ERR ) {
... ...
@@ -589,9 +604,6 @@ int main(int argc, char** argv)
589 589
 		goto error;
590 590
 	}
591 591
 
592
-	//memtest();
593
-	//hashtest();
594
-
595 592
 	/* process command line (get port no, cfg. file path etc) */
596 593
 	opterr=0;
597 594
 	options=
... ...
@@ -616,34 +628,43 @@ int main(int argc, char** argv)
616 616
 						fprintf(stderr, "bad port number: -p %s\n", optarg);
617 617
 						goto error;
618 618
 					}
619
+					if (sock_no>0) sock_info[sock_no-1].port_no=port_no;
619 620
 					break;
620 621
 
621 622
 			case 'm':
622 623
 					shm_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024;
623 624
 					if (tmp &&(*tmp)){
624
-						fprintf(stderr, "bad shmem size number: -m %s\n", optarg);
625
+						fprintf(stderr, "bad shmem size number: -m %s\n",
626
+										optarg);
625 627
 						goto error;
626 628
 					};
627
-					LOG(L_INFO, "ser: shared memory allocated: %d MByte\n", shm_mem_size );
629
+					LOG(L_INFO, "ser: shared memory allocated: %d MByte\n",
630
+									shm_mem_size );
628 631
 					break;
629 632
 
630 633
 			case 'b':
631 634
 					maxbuffer=strtol(optarg, &tmp, 10);
632 635
 					if (tmp &&(*tmp)){
633
-                                                fprintf(stderr, "bad max buffer size number: -p %s\n", optarg);
634
-                                                goto error;
635
-                                        }
636
-                                        break;
636
+						fprintf(stderr, "bad max buffer size number: -p %s\n",
637
+											optarg);
638
+						goto error;
639
+					}
640
+					break;
637 641
 			case 'l':
638 642
 					/* add a new addr. to our address list */
639
-					if (addresses_no < MAX_LISTEN){
640
-						names[addresses_no]=(char*)malloc(strlen(optarg)+1);
641
-						if (names[addresses_no]==0){
643
+					if (sock_no < MAX_LISTEN){
644
+						sock_info[sock_no].name.s=
645
+										(char*)malloc(strlen(optarg)+1);
646
+						if (sock_info[sock_no].name.s==0){
642 647
 							fprintf(stderr, "Out of memory.\n");
643 648
 							goto error;
644 649
 						}
645
-						strncpy(names[addresses_no], optarg, strlen(optarg)+1);
646
-						addresses_no++;
650
+						strncpy(sock_info[sock_no].name.s, optarg,
651
+												strlen(optarg)+1);
652
+						sock_info[sock_no].name.len=strlen(optarg);
653
+						/* set default port */
654
+						sock_info[sock_no].port_no=port_no;
655
+						sock_no++;
647 656
 					}else{
648 657
 						fprintf(stderr, 
649 658
 									"Too many addresses (max. %d).\n",
... ...
@@ -654,7 +675,8 @@ int main(int argc, char** argv)
654 654
 			case 'n':
655 655
 					children_no=strtol(optarg, &tmp, 10);
656 656
 					if ((tmp==0) ||(*tmp)){
657
-						fprintf(stderr, "bad process number: -n %s\n", optarg);
657
+						fprintf(stderr, "bad process number: -n %s\n",
658
+									optarg);
658 659
 						goto error;
659 660
 					}
660 661
 					break;
... ...
@@ -784,16 +806,6 @@ int main(int argc, char** argv)
784 784
 
785 785
 	/* fix parameters */
786 786
 	if (port_no<=0) port_no=SIP_PORT;
787
-	port_no_str_len=snprintf(port_no_str, MAX_PORT_LEN, ":%d", 
788
-				(unsigned short) port_no);
789
-	if (port_no_str_len<0){
790
-		fprintf(stderr, "ERROR: bad port number: %d\n", port_no);
791
-		goto error;
792
-	}
793
-	/* on some system snprintf return really strange things if it does not 
794
-	   have  enough space */
795
-	port_no_str_len=
796
-				(port_no_str_len<MAX_PORT_LEN)?port_no_str_len:MAX_PORT_LEN;
797 787
 
798 788
 	
799 789
 	if (children_no<=0) children_no=CHILD_NO;
... ...
@@ -817,42 +829,63 @@ int main(int argc, char** argv)
817 817
 	}
818 818
 	memset(pids, 0, sizeof(int)*(children_no+1));
819 819
 
820
-	if (addresses_no==0) {
820
+	if (sock_no==0) {
821 821
 		/* get our address, only the first one */
822 822
 		if (uname (&myname) <0){
823 823
 			fprintf(stderr, "cannot determine hostname, try -l address\n");
824 824
 			goto error;
825 825
 		}
826
-		names[addresses_no]=(char*)malloc(strlen(myname.nodename)+1);
827
-		if (names[addresses_no]==0){
826
+		sock_info[sock_no].name.s=(char*)malloc(strlen(myname.nodename)+1);
827
+		if (sock_info[sock_no].name.s==0){
828 828
 			fprintf(stderr, "Out of memory.\n");
829 829
 			goto error;
830 830
 		}
831
-		strncpy(names[addresses_no], myname.nodename,
831
+		strncpy(sock_info[sock_no].name.s, myname.nodename,
832 832
 				strlen(myname.nodename)+1);
833
-		addresses_no++;
833
+		sock_info[sock_no].name.len=strlen(myname.nodename);
834
+		sock_no++;
834 835
 	}
835 836
 
836
-	/*get name lens*/
837
-	for(r=0; r<addresses_no; r++){
838
-		names_len[r]=strlen(names[r]);
839
-	}
840
-
841
-	
842
-	/* get ips */
837
+	/* get ips & fill the port numbers*/
843 838
 	printf("Listening on ");
844
-	for (r=0; r<addresses_no;r++){
845
-		he=resolvehost(names[r]);
839
+	for (r=0; r<sock_no;r++){
840
+		he=resolvehost(sock_info[r].name.s);
846 841
 		if (he==0){
847
-			DPrint("ERROR: could not resolve %s\n", names[r]);
842
+			DPrint("ERROR: could not resolve %s\n", sock_info[r].name.s);
848 843
 			goto error;
849 844
 		}
850
-		hostent2ip_addr(&addresses[r], he, 0); /*convert to ip_addr format*/
851
-		/*memcpy(&addresses[r], he->h_addr_list[0], sizeof(int));*/
852
-		/*addresses[r]=*((long*)he->h_addr_list[0]);*/
853
-		printf("%s [",names[r]);
854
-		stdout_print_ip(&addresses[r]);
855
-		printf("]:%d\n", (unsigned short)port_no);
845
+		hostent2ip_addr(&sock_info[r].address, he, 0); /*convert to ip_addr format*/
846
+		tmp=ip_addr2a(&sock_info[r].address);
847
+		sock_info[r].address_str.s=(char*)malloc(strlen(tmp)+1);
848
+		if (sock_info[r].address_str.s==0){
849
+			fprintf(stderr, "Out of memory.\n");
850
+			goto error;
851
+		}
852
+		strncpy(sock_info[r].address_str.s, tmp, strlen(tmp)+1);
853
+		sock_info[r].address_str.len=strlen(tmp);
854
+		
855
+		if (sock_info[r].port_no==0) sock_info[r].port_no=port_no;
856
+		port_no_str_len=snprintf(port_no_str, MAX_PORT_LEN, ":%d", 
857
+									(unsigned short) sock_info[r].port_no);
858
+		if (port_no_str_len<0){
859
+			fprintf(stderr, "ERROR: bad port number: %d\n", 
860
+						sock_info[r].port_no);
861
+			goto error;
862
+		}
863
+		/* on some system snprintf return really strange things if it does not 
864
+			have  enough space */
865
+		port_no_str_len=
866
+				(port_no_str_len<MAX_PORT_LEN)?port_no_str_len:MAX_PORT_LEN;
867
+		sock_info[r].port_no_str.s=(char*)malloc(strlen(port_no_str)+1);
868
+		if (sock_info[r].port_no_str.s==0){
869
+			fprintf(stderr, "Out of memory.\n");
870
+			goto error;
871
+		}
872
+		strncpy(sock_info[r].port_no_str.s, port_no_str, strlen(port_no_str)+1);
873
+		sock_info[r].port_no_str.len=strlen(port_no_str);
874
+		
875
+		printf("%s [%s]:%s\n",sock_info[r].name.s, sock_info[r].address_str.s,
876
+				sock_info[r].port_no_str.s);
856 877
 	}
857 878
 
858 879
 #ifdef STATS
... ...
@@ -89,30 +89,45 @@ int check_address(struct ip_addr* ip, char *name, int resolver)
89 89
 
90 90
 
91 91
 
92
-char* via_builder( struct sip_msg *msg , unsigned int *len )
92
+char* via_builder( struct sip_msg *msg , unsigned int *len, 
93
+					struct socket_info* send_sock )
93 94
 {
94
-	unsigned int  via_len, branch_len;
95
+	unsigned int  via_len, branch_len, extra_len;;
95 96
 	char               *line_buf;
96 97
 
97 98
 	line_buf=0;
99
+	extra_len=0;
98 100
 
99 101
 	line_buf=pkg_malloc(sizeof(char)*MAX_VIA_LINE_SIZE);
100 102
 	if (line_buf==0){
101 103
 		LOG(L_ERR, "ERROR: via_builder: out of memory\n");
102 104
 		goto error;
103 105
 	}
104
-	via_len=MY_VIA_LEN+names_len[0]; /* space included in MY_VIA*/
106
+	via_len=MY_VIA_LEN+send_sock->address_str.len; /*space included in MY_VIA*/
107
+#ifdef USE_IPV6
108
+	if (send_sock->address.af==AF_INET6) via_len+=2; /* [ ]*/
109
+#endif
105 110
 
106 111
 	/* jku: if we compute branches using MD5 it will take 32 bytes */
107 112
 	branch_len= (loop_checks ? MY_BRANCH_LEN : MY_BRANCH_LEN -1 + MD5_LEN)+
108 113
 					msg->add_to_branch_len;
109 114
 
110
-	if ((via_len+port_no_str_len+branch_len+CRLF_LEN)<MAX_VIA_LINE_SIZE){
115
+	if ((via_len+send_sock->port_no_str.len+branch_len
116
+								+CRLF_LEN)<MAX_VIA_LINE_SIZE){
111 117
 		memcpy(line_buf, MY_VIA, MY_VIA_LEN);
112
-		memcpy(line_buf+MY_VIA_LEN, names[0], names_len[0]);
113
-		if (port_no!=SIP_PORT){
114
-			memcpy(line_buf+via_len, port_no_str, port_no_str_len);
115
-			via_len+=port_no_str_len;
118
+#ifdef USE_IPV6
119
+	if (send_sock->address.af==AF_INET6) {
120
+		line_buf[MY_VIA_LEN]='[';
121
+		line_buf[MY_VIA_LEN+1+send_sock->address_str.len]=']';
122
+		extra_len=1;
123
+	}
124
+#endif
125
+		memcpy(line_buf+MY_VIA_LEN+extra_len, send_sock->address_str.s,
126
+									send_sock->address_str.len);
127
+		if (send_sock->port_no!=SIP_PORT){
128
+			memcpy(line_buf+via_len, send_sock->port_no_str.s,
129
+									 send_sock->port_no_str.len);
130
+			via_len+=send_sock->port_no_str.len;
116 131
 		}
117 132
 
118 133
 		/* jku: branch parameter */
... ...
@@ -222,7 +237,8 @@ done:
222 222
 
223 223
 
224 224
 char * build_req_buf_from_sip_req( struct sip_msg* msg,
225
-								unsigned int *returned_len)
225
+								unsigned int *returned_len,
226
+								struct socket_info* send_sock)
226 227
 {
227 228
 	unsigned int len, new_len, received_len, uri_len, via_len, extra_len;
228 229
 	char* line_buf;
... ...
@@ -249,7 +265,7 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
249 249
 	extra_len=0;
250 250
 
251 251
 
252
-	line_buf = via_builder( msg, &via_len );
252
+	line_buf = via_builder( msg, &via_len, send_sock);
253 253
 	if (!line_buf){
254 254
 		LOG(L_ERR,"ERROR: build_req_buf_from_sip_req: no via received!\n");
255 255
 		goto error1;
... ...
@@ -9,9 +9,10 @@
9 9
 #define MY_HF_SEP_LEN 2
10 10
 
11 11
 #include "parser/msg_parser.h"
12
+#include "ip_addr.h"
12 13
 
13 14
 char * build_req_buf_from_sip_req (	struct sip_msg* msg, 
14
-				unsigned int *returned_len);
15
+				unsigned int *returned_len, struct socket_info* send_sock);
15 16
 
16 17
 char * build_res_buf_from_sip_res(	struct sip_msg* msg,
17 18
 				unsigned int *returned_len);
... ...
@@ -23,7 +24,7 @@ char * build_res_buf_from_sip_req(	unsigned int code ,
23 23
 				struct sip_msg* msg,
24 24
 				unsigned int *returned_len);
25 25
 char* via_builder( 			struct sip_msg *msg ,
26
-				unsigned int *len );
26
+				unsigned int *len, struct socket_info* send_sock);
27 27
 
28 28
 
29 29
 #endif
... ...
@@ -43,7 +43,7 @@ int receive_msg(char* buf, unsigned int len, union sockaddr_union* src_su)
43 43
 	msg->buf=buf;
44 44
 	msg->len=len;
45 45
 	su2ip_addr(&msg->src_ip, src_su);
46
-	msg->dst_ip=*bind_address; /* won't work if listening on 0.0.0.0 */
46
+	msg->dst_ip=bind_address->address; /* won't work if listening on 0.0.0.0 */
47 47
 	msg->id=msg_no;
48 48
 	/* make a copy of the message */
49 49
 	msg->orig=(char*) pkg_malloc(len+1);
... ...
@@ -23,7 +23,6 @@
23 23
 #include <mem/dmalloc.h>
24 24
 #endif
25 25
 
26
-int udp_sock;
27 26
 
28 27
 int probe_max_receive_buffer( int udp_sock )
29 28
 {
... ...
@@ -107,7 +106,7 @@ int probe_max_receive_buffer( int udp_sock )
107 107
 	/* EoJKU */
108 108
 }
109 109
 
110
-int udp_init(struct ip_addr* ip, unsigned short port)
110
+int udp_init(struct socket_info* sock_info)
111 111
 {
112 112
 	union sockaddr_union* addr;
113 113
 	int optval;
... ...
@@ -119,7 +118,7 @@ int udp_init(struct ip_addr* ip, unsigned short port)
119 119
 		goto error;
120 120
 	}
121 121
 	
122
-	if (init_su(addr, ip, htons(port))<0){
122
+	if (init_su(addr, &sock_info->address, htons(sock_info->port_no))<0){
123 123
 		LOG(L_ERR, "ERROR: udp_init: could not init sockaddr_union\n");
124 124
 		goto error;
125 125
 	}
... ...
@@ -130,25 +129,33 @@ int udp_init(struct ip_addr* ip, unsigned short port)
130 130
 	*/
131 131
 
132 132
 	
133
-	udp_sock = socket(AF2PF(addr->s.sa_family), SOCK_DGRAM, 0);
134
-	if (udp_sock==-1){
133
+	sock_info->socket = socket(AF2PF(addr->s.sa_family), SOCK_DGRAM, 0);
134
+	if (sock_info->socket==-1){
135 135
 		LOG(L_ERR, "ERROR: udp_init: socket: %s\n", strerror(errno));
136 136
 		goto error;
137 137
 	}
138 138
 	/* set sock opts? */
139 139
 	optval=1;
140
-	if (setsockopt(udp_sock, SOL_SOCKET, SO_REUSEADDR ,
140
+	if (setsockopt(sock_info->socket, SOL_SOCKET, SO_REUSEADDR ,
141 141
 					(void*)&optval, sizeof(optval)) ==-1)
142 142
 	{
143 143
 		LOG(L_ERR, "ERROR: udp_init: setsockopt: %s\n", strerror(errno));
144 144
 		goto error;
145 145
 	}
146 146
 
147
-	if ( probe_max_receive_buffer(udp_sock)==-1) goto error;
148
-	bind_address=ip;
149
-
150
-	if (bind(udp_sock,  &addr->s, sizeof(union sockaddr_union))==-1){
151
-		LOG(L_ERR, "ERROR: udp_init: bind: %s\n", strerror(errno));
147
+	if ( probe_max_receive_buffer(sock_info->socket)==-1) goto error;
148
+
149
+	if (bind(sock_info->socket,  &addr->s, sizeof(union sockaddr_union))==-1){
150
+		LOG(L_ERR, "ERROR: udp_init: bind(%x, %p, %d) on %s: %s\n",
151
+				sock_info->socket, &addr->s, 
152
+				sizeof(union sockaddr_union),
153
+				sock_info->address_str.s,
154
+				strerror(errno));
155
+	#ifdef USE_IPV6
156
+		if (addr->s.sa_family==AF_INET6)
157
+			LOG(L_ERR, "ERROR: udp_init: might be caused by using a link "
158
+					" local address, try site local or global\n");
159
+	#endif
152 160
 		goto error;
153 161
 	}
154 162
 
... ...
@@ -191,8 +198,8 @@ int udp_rcv_loop()
191 191
 		}
192 192
 #endif
193 193
 		fromlen=sizeof(union sockaddr_union);
194
-		len=recvfrom(udp_sock, buf, BUF_SIZE, 0, &from->s,
195
-						&fromlen);
194
+		len=recvfrom(bind_address->socket, buf, BUF_SIZE, 0, &from->s,
195
+											&fromlen);
196 196
 		if (len==-1){
197 197
 			LOG(L_ERR, "ERROR: udp_rcv_loop:recvfrom:[%d] %s\n",
198 198
 						errno, strerror(errno));
... ...
@@ -222,15 +229,15 @@ error:
222 222
 
223 223
 
224 224
 /* which socket to use? main socket or new one? */
225
-int udp_send(char *buf, unsigned len, union sockaddr_union*  to,
226
-				unsigned tolen)
225
+int udp_send(struct socket_info *source, char *buf, unsigned len,
226
+				union sockaddr_union*  to, unsigned tolen)
227 227
 {
228 228
 
229 229
 	int n;
230 230
 
231 231
 
232 232
 again:
233
-	n=sendto(udp_sock, buf, len, 0, &to->s, tolen);
233
+	n=sendto(source->socket, buf, len, 0, &to->s, tolen);
234 234
 	if (n==-1){
235 235
 		LOG(L_ERR, "ERROR: udp_send: sendto(sock,%p,%d,0,%p,%d): %s(%d)\n",
236 236
 				buf,len,to,tolen,
... ...
@@ -12,11 +12,10 @@
12 12
 #define MAX_RECV_BUFFER_SIZE	256*1024
13 13
 #define BUFFER_INCREMENT	2048
14 14
 
15
-extern int udp_sock;
16 15
 
17
-int udp_init(struct ip_addr* ip, unsigned short port);
18
-int udp_send(char *buf, unsigned len, union sockaddr_union*  to,
19
-				unsigned tolen);
16
+int udp_init(struct socket_info* si);
17
+int udp_send(struct socket_info* source,char *buf, unsigned len,
18
+				union sockaddr_union*  to, unsigned tolen);
20 19
 int udp_rcv_loop();
21 20
 
22 21