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 145
 			if (ret==0){
145 146
 				p->tx++;
146 147
 				p->tx_bytes+=msg->len;
147
-				ret=udp_send(msg->orig, msg->len, to,
148
-								sizeof(union sockaddr_union));
148
+				send_sock=get_send_socket(to);
149
+				if (send_sock!=0){
150
+					ret=udp_send(send_sock, msg->orig, msg->len, to,
151
+									sizeof(union sockaddr_union));
152
+				}else{
153
+					ret=-1;
154
+				}
149 155
 			}
150 156
 			free(to);
151 157
 			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 183
 		| LOOP_CHECKS EQUAL NUMBER { loop_checks=$3; }
181 184
 		| LOOP_CHECKS EQUAL error { yyerror("boolean value expected"); }
182 185
 		| LISTEN EQUAL ip  {
183
-								if (addresses_no < MAX_LISTEN){
186
+								if (sock_no< MAX_LISTEN){
184 187
 									tmp=ip_addr2a($3);
185 188
 								/*	tmp=inet_ntoa(*(struct in_addr*)&$3);*/
186 189
 									if (tmp==0){
... ...
@@ -188,15 +191,19 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
188 191
 											" bad ip address: %s\n",
189 192
 											strerror(errno));
190 193
 									}else{
191
-										names[addresses_no]=
194
+										sock_info[sock_no].name.s=
192 195
 												(char*)malloc(strlen(tmp)+1);
193
-										if (names[addresses_no]==0){
196
+										if (sock_info[sock_no].name.s==0){
194 197
 											LOG(L_CRIT, "ERROR: cfg. parser: "
195 198
 														"out of memory.\n");
196 199
 										}else{
197
-											strncpy(names[addresses_no], tmp,
198
-													strlen(tmp)+1);
199
-											addresses_no++;
200
+											strncpy(sock_info[sock_no].name.s,
201
+													tmp, strlen(tmp)+1);
202
+											sock_info[sock_no].name.len=
203
+													strlen(tmp);
204
+											sock_info[sock_no].port_no=
205
+													port_no;
206
+											sock_no++;
200 207
 										}
201 208
 									}
202 209
 								}else{
... ...
@@ -206,16 +213,18 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
206 213
 								}
207 214
 							  }
208 215
 		| LISTEN EQUAL ID	 {
209
-								if (addresses_no < MAX_LISTEN){
210
-									names[addresses_no]=
216
+								if (sock_no < MAX_LISTEN){
217
+									sock_info[sock_no].name.s=
211 218
 												(char*)malloc(strlen($3)+1);
212
-									if (names[addresses_no]==0){
219
+									if (sock_info[sock_no].name.s==0){
213 220
 										LOG(L_CRIT, "ERROR: cfg. parser:"
214 221
 														" out of memory.\n");
215 222
 									}else{
216
-										strncpy(names[addresses_no], $3,
223
+										strncpy(sock_info[sock_no].name.s, $3,
217 224
 													strlen($3)+1);
218
-										addresses_no++;
225
+										sock_info[sock_no].name.len=strlen($3);
226
+										sock_info[sock_no].port_no= port_no;
227
+										sock_no++;
219 228
 									}
220 229
 								}else{
221 230
 									LOG(L_CRIT, "ERROR: cfg. parser: "
... ...
@@ -224,16 +233,18 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
224 233
 								}
225 234
 							  }
226 235
 		| LISTEN EQUAL STRING {
227
-								if (addresses_no < MAX_LISTEN){
228
-									names[addresses_no]=
236
+								if (sock_no < MAX_LISTEN){
237
+									sock_info[sock_no].name.s=
229 238
 										(char*)malloc(strlen($3)+1);
230
-									if (names[addresses_no]==0){
239
+									if (sock_info[sock_no].name.s==0){
231 240
 										LOG(L_CRIT, "ERROR: cfg. parser:"
232 241
 													" out of memory.\n");
233 242
 									}else{
234
-										strncpy(names[addresses_no], $3,
243
+										strncpy(sock_info[sock_no].name.s, $3,
235 244
 												strlen($3)+1);
236
-										addresses_no++;
245
+										sock_info[sock_no].name.len=strlen($3);
246
+										sock_info[sock_no].port_no=port_no;
247
+										sock_no++;
237 248
 									}
238 249
 								}else{
239 250
 									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 85
 		else p->addr_idx=0;
65 86
 		p->ok=1;
66 87
 	}
67
-
88
+	
68 89
 	hostent2su(to, &p->host, p->addr_idx, 
69 90
 				(p->port)?htons(p->port):htons(SIP_PORT));
70 91
 	p->tx++;
71 92
 	p->tx_bytes+=len;
93
+	
72 94
 
73
-	if (udp_send( buf, len,  to, sizeof(union sockaddr_union))==-1){
95
+	send_sock=get_send_socket(to);
96
+	if (send_sock==0){
97
+		LOG(L_ERR, "forward_req: ERROR: cannot forward to af %d "
98
+				"no coresponding listening socket\n", to->s.sa_family);
99
+		goto error;
100
+	}
101
+	
102
+	buf = build_req_buf_from_sip_req( msg, &len, send_sock);
103
+	if (!buf){
104
+		LOG(L_ERR, "ERROR: forward_reply: building failed\n");
105
+		goto error;
106
+	}
107
+	 /* send it! */
108
+	DBG("Sending:\n%s.\n", buf);
109
+	DBG("orig. len=%d, new_len=%d\n", msg->len, len );
110
+	
111
+	if (udp_send( send_sock, buf, len,  to, 
112
+							sizeof(union sockaddr_union))==-1){
74 113
 			p->errors++;
75 114
 			p->ok=0;
76 115
 			STATS_TX_DROPS;
... ...
@@ -145,6 +184,7 @@ int forward_reply(struct sip_msg* msg)
145 184
 	int  r;
146 185
 	char* new_buf;
147 186
 	union sockaddr_union* to;
187
+	struct socket_info* send_sock;
148 188
 	unsigned int new_len;
149 189
 	struct sr_module *mod;
150 190
 	
... ...
@@ -152,11 +192,14 @@ int forward_reply(struct sip_msg* msg)
152 192
 	new_buf=0;
153 193
 	/*check if first via host = us */
154 194
 	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){
195
+		for (r=0; r<sock_no; r++)
196
+			if ( (msg->via1->host.len==sock_info[r].name.len) && 
197
+					(memcmp(msg->via1->host.s, sock_info[r].name.s, 
198
+										sock_info[r].name.len)==0) )
199
+				break;
200
+		if (r==sock_no){
158 201
 			LOG(L_NOTICE, "ERROR: forward_reply: host in first via!=me :"
159
-					" %s\n", msg->via1->host.s);
202
+					" %.*s\n", msg->via1->host.len, msg->via1->host.s);
160 203
 			/* send error msg back? */
161 204
 			goto error;
162 205
 		}
... ...
@@ -192,8 +235,13 @@ int forward_reply(struct sip_msg* msg)
192 235
 	}
193 236
 
194 237
 	if (update_sock_struct_from_via( to, msg->via2 )==-1) goto error;
238
+	send_sock=get_send_socket(to);
239
+	if (send_sock==0){
240
+		LOG(L_ERR, "forward_reply: ERROR: no sending socket found\n");
241
+		goto error;
242
+	}
195 243
 
196
-	if (udp_send(new_buf,new_len,  to,
244
+	if (udp_send(send_sock, new_buf,new_len,  to,
197 245
 				sizeof(union sockaddr_union))==-1)
198 246
 	{
199 247
 		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 50
 };
50 51
 
51 52
 
53
+struct socket_info{
54
+	int socket;
55
+	str name; /* name - eg.: foo.bar or 10.0.0.1 */
56
+	struct ip_addr address; /* ip address */
57
+	str address_str;        /* ip address converted to string -- optimization*/
58
+	unsigned short port_no;  /* port number */
59
+	str port_no_str; /* port number converted to string -- optimization*/
60
+};
61
+
52 62
 
53 63
 
54 64
 /* 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 225
 	register unsigned char a,b,c;
216 226
 #ifdef USE_IPV6
217 227
 	register unsigned char d;
228
+	register unsigned short hex4;
218 229
 #endif
219 230
 	int r;
220 231
 	#define HEXDIG(x) (((x)>=10)?(x)-10+'A':(x)+'0')
... ...
@@ -225,10 +236,11 @@ static inline char* ip_addr2a(struct ip_addr* ip)
225 236
 	#ifdef USE_IPV6
226 237
 		case AF_INET6:
227 238
 			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;
239
+				hex4=ntohs(ip->u.addr16[r]);
240
+				a=hex4>>12;
241
+				b=(hex4>>8)&0xf;
242
+				c=(hex4>>4)&0xf;
243
+				d=hex4&0xf;
232 244
 				if (a){
233 245
 					buff[offset]=HEXDIG(a);
234 246
 					buff[offset+1]=HEXDIG(b);
... ...
@@ -254,10 +266,11 @@ static inline char* ip_addr2a(struct ip_addr* ip)
254 266
 				}
255 267
 			}
256 268
 			/* 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;
269
+			hex4=ntohs(ip->u.addr16[r]);
270
+			a=hex4>>12;
271
+			b=(hex4>>8)&0xf;
272
+			c=(hex4>>4)&0xf;
273
+			d=hex4&0xf;
261 274
 			if (a){
262 275
 				buff[offset]=HEXDIG(a);
263 276
 				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 197
 /* global vars */
196 198
 
197 199
 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 200
 unsigned int maxbuffer = MAX_RECV_BUFFER_SIZE; /* maximum buffer size we do
202 201
 												  not want to exceed durig the
203 202
 												  auto-probing procedure; may 
... ...
@@ -217,11 +216,20 @@ char* chroot_dir = 0;
217 216
 int uid = 0;
218 217
 int gid = 0;
219 218
 
219
+#if 0
220 220
 char* names[MAX_LISTEN];              /* our names */
221 221
 int names_len[MAX_LISTEN];            /* lengths of the names*/
222 222
 struct ip_addr addresses[MAX_LISTEN]; /* our ips */
223 223
 int addresses_no=0;                   /* number of names/ips */
224
-struct ip_addr* bind_address;        /* listen address of the crt. process */
224
+#endif
225
+struct socket_info sock_info[MAX_LISTEN]; /* all addresses we listen/send from*/
226
+int sock_no=0; /* number of addresses/open sockets*/
227
+struct socket_info* bind_address; /* pointer to the crt. proc. listening address */
228
+int bind_idx; /* same as above but index in the bound[] array */
229
+struct socket_info* sendipv4; /* ipv4 socket to use when msg. comes from ipv6*/
230
+struct socket_info* sendipv6; /* same as above for ipv6 */
231
+
232
+unsigned short port_no=0; /* default port*/
225 233
 
226 234
 /* ipc related globals */
227 235
 int process_no = 0;
... ...
@@ -246,7 +254,6 @@ extern int yyparse();
246 254
 static int is_main=0; /* flag = is this the  "main" process? */
247 255
 
248 256
 char* pid_file = 0; /* filename as asked by use */
249
-char *pid_fn = 0; /* and with port number appended */
250 257
 
251 258
 /* daemon init, return 0 on success, -1 on error */
252 259
 int daemonize(char*  name)
... ...
@@ -255,7 +262,6 @@ int daemonize(char*  name)
255 262
 	pid_t pid;
256 263
 	int r, p;
257 264
 
258
-	int pid_fn_len;
259 265
 
260 266
 	p=-1;
261 267
 
... ...
@@ -288,8 +294,7 @@ int daemonize(char*  name)
288 294
 	if ((pid=fork())<0){
289 295
 		LOG(L_CRIT, "Cannot fork:%s\n", strerror(errno));
290 296
 		goto error;
291
-	}
292
-	if (pid!=0){
297
+	}else if (pid!=0){
293 298
 		/* parent process => exit*/
294 299
 		exit(0);
295 300
 	}
... ...
@@ -301,49 +306,34 @@ int daemonize(char*  name)
301 306
 	if ((pid=fork())<0){
302 307
 		LOG(L_CRIT, "Cannot  fork:%s\n", strerror(errno));
303 308
 		goto error;
304
-	}
305
-	if (pid!=0){
309
+	}else if (pid!=0){
306 310
 		/*parent process => exit */
307 311
 		exit(0);
308 312
 	}
309 313
 
310 314
 	/* added by noh: create a pid file for the main process */
311 315
 	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 316
 		
326
-			
327
-		if ((pid_stream=fopen(pid_fn, "r"))!=NULL){
317
+		if ((pid_stream=fopen(pid_file, "r"))!=NULL){
328 318
 			fscanf(pid_stream, "%d", &p);
329 319
 			fclose(pid_stream);
330 320
 			if (p==-1){
331 321
 				LOG(L_CRIT, "pid file %s exists, but doesn't contain a valid"
332
-					" pid number\n", pid_fn);
322
+					" pid number\n", pid_file);
333 323
 				goto error;
334 324
 			}
335 325
 			if (kill((pid_t)p, 0)==0 || errno==EPERM){
336 326
 				LOG(L_CRIT, "running process found in the pid file %s\n",
337
-					pid_fn);
327
+					pid_file);
338 328
 				goto error;
339 329
 			}else{
340 330
 				LOG(L_WARN, "pid file contains old pid, replacing pid\n");
341 331
 			}
342 332
 		}
343 333
 		pid=getpid();
344
-		if ((pid_stream=fopen(pid_fn, "w"))==NULL){
334
+		if ((pid_stream=fopen(pid_file, "w"))==NULL){
345 335
 			LOG(L_WARN, "unable to create pid file %s: %s\n", 
346
-				pid_fn, strerror(errno));
336
+				pid_file, strerror(errno));
347 337
 			goto error;
348 338
 		}else{
349 339
 			fprintf(pid_stream, "%i\n", (int)pid);
... ...
@@ -378,14 +368,19 @@ int main_loop()
378 368
 #ifdef STATS
379 369
 		setstats( 0 );
380 370
 #endif
381
-		/* only one address */
382
-		if (udp_init(&addresses[0],port_no)==-1) goto error;
371
+		/* only one address, we ignore all the others */
372
+		if (udp_init(&sock_info[0])==-1) goto error;
373
+		bind_address=&sock_info[0];
374
+		bind_idx=0;
375
+		if (sock_no>1){
376
+			LOG(L_WARN, "WARNING: using only the first listen address (no fork)\n");
377
+		}
383 378
 
384 379
 		/* we need another process to act as the timer*/
385 380
 		if (timer_list){
386 381
 				process_no++;
387 382
 				if ((pid=fork())<0){
388
-					LOG(L_CRIT,  "ERRROR: main_loop: Cannot fork\n");
383
+					LOG(L_CRIT,  "ERROR: main_loop: Cannot fork\n");
389 384
 					goto error;
390 385
 				}
391 386
 				
... ...
@@ -418,17 +413,28 @@ int main_loop()
418 413
 		
419 414
 		return udp_rcv_loop();
420 415
 	}else{
421
-		for(r=0;r<addresses_no;r++){
416
+		for(r=0;r<sock_no;r++){
422 417
 			/* create the listening socket (for each address)*/
423
-			if (udp_init(&addresses[r], port_no)==-1) goto error;
418
+			if (udp_init(&sock_info[r])==-1) goto error;
419
+			/* get first ipv4/ipv6 socket*/
420
+			if ((sendipv4==0)&&(sock_info[r].address.af==AF_INET))
421
+				sendipv4=&sock_info[r];
422
+	#ifdef USE_IPV6
423
+			if((sendipv6==0)&&(sock_info[r].address.af==AF_INET6))
424
+				sendipv6=&sock_info[r];
425
+	#endif
426
+			/* all procs should have access to all the sockets (for sending)
427
+			 * so we open all first*/
428
+		}
429
+		for(r=0; r<sock_no;r++){
424 430
 			for(i=0;i<children_no;i++){
425 431
 				if ((pid=fork())<0){
426 432
 					LOG(L_CRIT,  "main_loop: Cannot fork\n");
427 433
 					goto error;
428
-				}
429
-				if (pid==0){
434
+				}else if (pid==0){
430 435
 					     /* child */
431
-
436
+					bind_address=&sock_info[r]; /* shortcut */
437
+					bind_idx=r;
432 438
 					if (init_child(i) < 0) {
433 439
 						LOG(L_ERR, "init_child failed\n");
434 440
 						goto error;
... ...
@@ -452,6 +458,9 @@ int main_loop()
452 458
 	pids[process_no]=getpid();
453 459
 	process_bit = 0;
454 460
 	is_main=1;
461
+	bind_address=&sock_info[0]; /* main proc -> it shoudln't send anything, if it does */
462
+	bind_idx=0;					/*   it will use the first address */
463
+
455 464
 	if (timer_list){
456 465
 		for(;;){
457 466
 			/* debug:  instead of doing something usefull */
... ...
@@ -461,7 +470,7 @@ int main_loop()
461 470
 			timer_ticker();
462 471
 		}
463 472
 	}else{
464
-		for(;;) sleep(LONG_SLEEP);
473
+		for(;;) pause(); 
465 474
 	}
466 475
 	
467 476
 	/*return 0; */
... ...
@@ -474,8 +483,7 @@ int main_loop()
474 483
 /* added by jku; allows for regular exit on a specific signal;
475 484
    good for profiling which only works if exited regularly and
476 485
    not by default signal handlers
477
-*/	
478
-
486
+*/
479 487
 static void sig_usr(int signo)
480 488
 {
481 489
 	pid_t	chld;
... ...
@@ -508,6 +516,8 @@ static void sig_usr(int signo)
508 516
 		}
509 517
 #endif
510 518
 		dprint("Thank you for flying " NAME "\n");
519
+		/* kill children also*/
520
+		kill(0, SIGTERM);
511 521
 		exit(0);
512 522
 	} else if (signo==SIGTERM) { /* exit gracefully as daemon */
513 523
 		DPrint("TERM received, program terminates\n");
... ...
@@ -515,11 +525,11 @@ static void sig_usr(int signo)
515 525
 #ifdef STATS
516 526
 			dump_all_statistic();
517 527
 #endif
518
-			if (pid_fn) {
519
-				unlink(pid_fn);
520
-				free(pid_fn);
528
+			if (pid_file) {
529
+				unlink(pid_file);
521 530
 			}
522 531
 		}
532
+		kill(0, SIGTERM);
523 533
 		exit(0);
524 534
 	} else if (signo==SIGUSR1) { /* statistic */
525 535
 #ifdef STATS
... ...
@@ -549,6 +559,9 @@ static void sig_usr(int signo)
549 559
 				LOG(L_INFO, "child process %d stopped by a signal %d\n",
550 560
 					chld, WSTOPSIG(chld_status));
551 561
 		}
562
+		/* exit */
563
+		kill(0, SIGTERM);
564
+		exit(0);
552 565
 	}
553 566
 }
554 567
 
... ...
@@ -564,6 +577,8 @@ int main(int argc, char** argv)
564 577
 	char *tmp;
565 578
 	struct utsname myname;
566 579
 	char *options;
580
+	char port_no_str[MAX_PORT_LEN];
581
+	int port_no_str_len=0;
567 582
 
568 583
 	/* added by jku: add exit handler */
569 584
 	if (signal(SIGINT, sig_usr) == SIG_ERR ) {
... ...
@@ -589,9 +604,6 @@ int main(int argc, char** argv)
589 604
 		goto error;
590 605
 	}
591 606
 
592
-	//memtest();
593
-	//hashtest();
594
-
595 607
 	/* process command line (get port no, cfg. file path etc) */
596 608
 	opterr=0;
597 609
 	options=
... ...
@@ -616,34 +628,43 @@ int main(int argc, char** argv)
616 628
 						fprintf(stderr, "bad port number: -p %s\n", optarg);
617 629
 						goto error;
618 630
 					}
631
+					if (sock_no>0) sock_info[sock_no-1].port_no=port_no;
619 632
 					break;
620 633
 
621 634
 			case 'm':
622 635
 					shm_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024;
623 636
 					if (tmp &&(*tmp)){
624
-						fprintf(stderr, "bad shmem size number: -m %s\n", optarg);
637
+						fprintf(stderr, "bad shmem size number: -m %s\n",
638
+										optarg);
625 639
 						goto error;
626 640
 					};
627
-					LOG(L_INFO, "ser: shared memory allocated: %d MByte\n", shm_mem_size );
641
+					LOG(L_INFO, "ser: shared memory allocated: %d MByte\n",
642
+									shm_mem_size );
628 643
 					break;
629 644
 
630 645
 			case 'b':
631 646
 					maxbuffer=strtol(optarg, &tmp, 10);
632 647
 					if (tmp &&(*tmp)){
633
-                                                fprintf(stderr, "bad max buffer size number: -p %s\n", optarg);
634
-                                                goto error;
635
-                                        }
636
-                                        break;
648
+						fprintf(stderr, "bad max buffer size number: -p %s\n",
649
+											optarg);
650
+						goto error;
651
+					}
652
+					break;
637 653
 			case 'l':
638 654
 					/* 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){
655
+					if (sock_no < MAX_LISTEN){
656
+						sock_info[sock_no].name.s=
657
+										(char*)malloc(strlen(optarg)+1);
658
+						if (sock_info[sock_no].name.s==0){
642 659
 							fprintf(stderr, "Out of memory.\n");
643 660
 							goto error;
644 661
 						}
645
-						strncpy(names[addresses_no], optarg, strlen(optarg)+1);
646
-						addresses_no++;
662
+						strncpy(sock_info[sock_no].name.s, optarg,
663
+												strlen(optarg)+1);
664
+						sock_info[sock_no].name.len=strlen(optarg);
665
+						/* set default port */
666
+						sock_info[sock_no].port_no=port_no;
667
+						sock_no++;
647 668
 					}else{
648 669
 						fprintf(stderr, 
649 670
 									"Too many addresses (max. %d).\n",
... ...
@@ -654,7 +675,8 @@ int main(int argc, char** argv)
654 675
 			case 'n':
655 676
 					children_no=strtol(optarg, &tmp, 10);
656 677
 					if ((tmp==0) ||(*tmp)){
657
-						fprintf(stderr, "bad process number: -n %s\n", optarg);
678
+						fprintf(stderr, "bad process number: -n %s\n",
679
+									optarg);
658 680
 						goto error;
659 681
 					}
660 682
 					break;
... ...
@@ -784,16 +806,6 @@ int main(int argc, char** argv)
784 806
 
785 807
 	/* fix parameters */
786 808
 	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 809
 
798 810
 	
799 811
 	if (children_no<=0) children_no=CHILD_NO;
... ...
@@ -817,42 +829,63 @@ int main(int argc, char** argv)
817 829
 	}
818 830
 	memset(pids, 0, sizeof(int)*(children_no+1));
819 831
 
820
-	if (addresses_no==0) {
832
+	if (sock_no==0) {
821 833
 		/* get our address, only the first one */
822 834
 		if (uname (&myname) <0){
823 835
 			fprintf(stderr, "cannot determine hostname, try -l address\n");
824 836
 			goto error;
825 837
 		}
826
-		names[addresses_no]=(char*)malloc(strlen(myname.nodename)+1);
827
-		if (names[addresses_no]==0){
838
+		sock_info[sock_no].name.s=(char*)malloc(strlen(myname.nodename)+1);
839
+		if (sock_info[sock_no].name.s==0){
828 840
 			fprintf(stderr, "Out of memory.\n");
829 841
 			goto error;
830 842
 		}
831
-		strncpy(names[addresses_no], myname.nodename,
843
+		strncpy(sock_info[sock_no].name.s, myname.nodename,
832 844
 				strlen(myname.nodename)+1);
833
-		addresses_no++;
845
+		sock_info[sock_no].name.len=strlen(myname.nodename);
846
+		sock_no++;
834 847
 	}
835 848
 
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 */
849
+	/* get ips & fill the port numbers*/
843 850
 	printf("Listening on ");
844
-	for (r=0; r<addresses_no;r++){
845
-		he=resolvehost(names[r]);
851
+	for (r=0; r<sock_no;r++){
852
+		he=resolvehost(sock_info[r].name.s);
846 853
 		if (he==0){
847
-			DPrint("ERROR: could not resolve %s\n", names[r]);
854
+			DPrint("ERROR: could not resolve %s\n", sock_info[r].name.s);
848 855
 			goto error;
849 856
 		}
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);
857
+		hostent2ip_addr(&sock_info[r].address, he, 0); /*convert to ip_addr format*/
858
+		tmp=ip_addr2a(&sock_info[r].address);
859
+		sock_info[r].address_str.s=(char*)malloc(strlen(tmp)+1);
860
+		if (sock_info[r].address_str.s==0){
861
+			fprintf(stderr, "Out of memory.\n");
862
+			goto error;
863
+		}
864
+		strncpy(sock_info[r].address_str.s, tmp, strlen(tmp)+1);
865
+		sock_info[r].address_str.len=strlen(tmp);
866
+		
867
+		if (sock_info[r].port_no==0) sock_info[r].port_no=port_no;
868
+		port_no_str_len=snprintf(port_no_str, MAX_PORT_LEN, ":%d", 
869
+									(unsigned short) sock_info[r].port_no);
870
+		if (port_no_str_len<0){
871
+			fprintf(stderr, "ERROR: bad port number: %d\n", 
872
+						sock_info[r].port_no);
873
+			goto error;
874
+		}
875
+		/* on some system snprintf return really strange things if it does not 
876
+			have  enough space */
877
+		port_no_str_len=
878
+				(port_no_str_len<MAX_PORT_LEN)?port_no_str_len:MAX_PORT_LEN;
879
+		sock_info[r].port_no_str.s=(char*)malloc(strlen(port_no_str)+1);
880
+		if (sock_info[r].port_no_str.s==0){
881
+			fprintf(stderr, "Out of memory.\n");
882
+			goto error;
883
+		}
884
+		strncpy(sock_info[r].port_no_str.s, port_no_str, strlen(port_no_str)+1);
885
+		sock_info[r].port_no_str.len=strlen(port_no_str);
886
+		
887
+		printf("%s [%s]:%s\n",sock_info[r].name.s, sock_info[r].address_str.s,
888
+				sock_info[r].port_no_str.s);
856 889
 	}
857 890
 
858 891
 #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 237
 
223 238
 
224 239
 char * build_req_buf_from_sip_req( struct sip_msg* msg,
225
-								unsigned int *returned_len)
240
+								unsigned int *returned_len,
241
+								struct socket_info* send_sock)
226 242
 {
227 243
 	unsigned int len, new_len, received_len, uri_len, via_len, extra_len;
228 244
 	char* line_buf;
... ...
@@ -249,7 +265,7 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
249 265
 	extra_len=0;
250 266
 
251 267
 
252
-	line_buf = via_builder( msg, &via_len );
268
+	line_buf = via_builder( msg, &via_len, send_sock);
253 269
 	if (!line_buf){
254 270
 		LOG(L_ERR,"ERROR: build_req_buf_from_sip_req: no via received!\n");
255 271
 		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 24
 				struct sip_msg* msg,
24 25
 				unsigned int *returned_len);
25 26
 char* via_builder( 			struct sip_msg *msg ,
26
-				unsigned int *len );
27
+				unsigned int *len, struct socket_info* send_sock);
27 28
 
28 29
 
29 30
 #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 106
 	/* EoJKU */
108 107
 }
109 108
 
110
-int udp_init(struct ip_addr* ip, unsigned short port)
109
+int udp_init(struct socket_info* sock_info)
111 110
 {
112 111
 	union sockaddr_union* addr;
113 112
 	int optval;
... ...
@@ -119,7 +118,7 @@ int udp_init(struct ip_addr* ip, unsigned short port)
119 118
 		goto error;
120 119
 	}
121 120
 	
122
-	if (init_su(addr, ip, htons(port))<0){
121
+	if (init_su(addr, &sock_info->address, htons(sock_info->port_no))<0){
123 122
 		LOG(L_ERR, "ERROR: udp_init: could not init sockaddr_union\n");
124 123
 		goto error;
125 124
 	}
... ...
@@ -130,25 +129,33 @@ int udp_init(struct ip_addr* ip, unsigned short port)
130 129
 	*/
131 130
 
132 131
 	
133
-	udp_sock = socket(AF2PF(addr->s.sa_family), SOCK_DGRAM, 0);
134
-	if (udp_sock==-1){
132
+	sock_info->socket = socket(AF2PF(addr->s.sa_family), SOCK_DGRAM, 0);
133
+	if (sock_info->socket==-1){
135 134
 		LOG(L_ERR, "ERROR: udp_init: socket: %s\n", strerror(errno));
136 135
 		goto error;
137 136
 	}
138 137
 	/* set sock opts? */
139 138
 	optval=1;
140
-	if (setsockopt(udp_sock, SOL_SOCKET, SO_REUSEADDR ,
139
+	if (setsockopt(sock_info->socket, SOL_SOCKET, SO_REUSEADDR ,
141 140
 					(void*)&optval, sizeof(optval)) ==-1)
142 141
 	{
143 142
 		LOG(L_ERR, "ERROR: udp_init: setsockopt: %s\n", strerror(errno));
144 143
 		goto error;
145 144
 	}
146 145
 
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));
146
+	if ( probe_max_receive_buffer(sock_info->socket)==-1) goto error;
147
+
148
+	if (bind(sock_info->socket,  &addr->s, sizeof(union sockaddr_union))==-1){
149
+		LOG(L_ERR, "ERROR: udp_init: bind(%x, %p, %d) on %s: %s\n",
150
+				sock_info->socket, &addr->s, 
151
+				sizeof(union sockaddr_union),
152
+				sock_info->address_str.s,
153
+				strerror(errno));
154
+	#ifdef USE_IPV6
155
+		if (addr->s.sa_family==AF_INET6)
156
+			LOG(L_ERR, "ERROR: udp_init: might be caused by using a link "
157
+					" local address, try site local or global\n");
158
+	#endif
152 159
 		goto error;
153 160
 	}
154 161
 
... ...
@@ -191,8 +198,8 @@ int udp_rcv_loop()
191 198
 		}
192 199
 #endif
193 200
 		fromlen=sizeof(union sockaddr_union);
194
-		len=recvfrom(udp_sock, buf, BUF_SIZE, 0, &from->s,
195
-						&fromlen);
201
+		len=recvfrom(bind_address->socket, buf, BUF_SIZE, 0, &from->s,
202
+											&fromlen);
196 203
 		if (len==-1){
197 204
 			LOG(L_ERR, "ERROR: udp_rcv_loop:recvfrom:[%d] %s\n",
198 205
 						errno, strerror(errno));
... ...
@@ -222,15 +229,15 @@ error:
222 229
 
223 230
 
224 231
 /* which socket to use? main socket or new one? */
225
-int udp_send(char *buf, unsigned len, union sockaddr_union*  to,
226
-				unsigned tolen)
232
+int udp_send(struct socket_info *source, char *buf, unsigned len,
233
+				union sockaddr_union*  to, unsigned tolen)
227 234
 {
228 235
 
229 236
 	int n;
230 237
 
231 238
 
232 239
 again:
233
-	n=sendto(udp_sock, buf, len, 0, &to->s, tolen);
240
+	n=sendto(source->socket, buf, len, 0, &to->s, tolen);
234 241
 	if (n==-1){
235 242
 		LOG(L_ERR, "ERROR: udp_send: sendto(sock,%p,%d,0,%p,%d): %s(%d)\n",
236 243
 				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