Browse code

core: relocation and refactoring on ip addr handling code

- many static inline functions moved from ip_addr.h to ip_addr.c, code
size for some of them increased over the time
- ipv6_hex_style can be set to "c" to have IPv6 addresses compacted and
using lowercase hexdigits (rfc5952#section-4.2.1), GH #2510
- when ipv6_hex_style="c", ip6tosbuf() uses POSIX inet_ntop(),
conforming with POSIX.1-2001, POSIX.1-2008

Daniel-Constantin Mierla authored on 19/10/2020 10:32:43
Showing 4 changed files
... ...
@@ -879,10 +879,12 @@ assign_stm:
879 879
 	| AUTO_BIND_IPV6 EQUAL NUMBER {IF_AUTO_BIND_IPV6(auto_bind_ipv6 = $3);}
880 880
 	| AUTO_BIND_IPV6 error { yyerror("boolean value expected"); }
881 881
 	| IPV6_HEX_STYLE EQUAL STRING {
882
-		ksr_ipv6_hex_style = $3;
883
-		if(ksr_ipv6_hex_style[0]!='a' && ksr_ipv6_hex_style[0]!='A') {
884
-			yyerror("expected \"a\" or \"A\" value");
882
+		ksr_ipv6_hex_style.s = $3;
883
+		if(ksr_ipv6_hex_style.s[0]!='a' && ksr_ipv6_hex_style.s[0]!='A'
884
+				&& ksr_ipv6_hex_style.s[0]!='c') {
885
+			yyerror("expected \"a\", \"A\" or \"c\" value");
885 886
 		}
887
+		ksr_ipv6_hex_style.len = strlen(ksr_ipv6_hex_style.s);
886 888
 	}
887 889
 	| IPV6_HEX_STYLE error { yyerror("string value expected"); }
888 890
 	| BIND_IPV6_LINK_LOCAL EQUAL NUMBER {sr_bind_ipv6_link_local = $3;}
... ...
@@ -220,7 +220,7 @@ extern char *_sr_uri_host_extra_chars;
220 220
 extern unsigned char *_ksr_hname_extra_chars;
221 221
 
222 222
 extern char *ksr_stats_namesep;
223
-extern char *ksr_ipv6_hex_style;
223
+extern str ksr_ipv6_hex_style;
224 224
 
225 225
 #ifdef USE_DNS_CACHE
226 226
 extern int dns_cache_init; /* if 0, the DNS cache is not initialized at startup */
... ...
@@ -15,8 +15,8 @@
15 15
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 16
  * GNU General Public License for more details.
17 17
  *
18
- * You should have received a copy of the GNU General Public License 
19
- * along with this program; if not, write to the Free Software 
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program; if not, write to the Free Software
20 20
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21 21
  */
22 22
 
... ...
@@ -29,6 +29,7 @@
29 29
 
30 30
 #include <stdlib.h>
31 31
 #include <stdio.h>
32
+#include <arpa/inet.h>
32 33
 
33 34
 #include "ip_addr.h"
34 35
 #include "dprint.h"
... ...
@@ -36,14 +37,354 @@
36 37
 #include "resolve.h"
37 38
 #include "trim.h"
38 39
 
39
-char *ksr_ipv6_hex_style = "A";
40
+str ksr_ipv6_hex_style = str_init("A");
41
+
42
+
43
+/* inits a struct sockaddr_union from a struct hostent, an address index in
44
+ * the hostent structure and a port no. (host byte order)
45
+ * WARNING: no index overflow  checks!
46
+ * returns 0 if ok, -1 on error (unknown address family) */
47
+int hostent2su(union sockaddr_union* su,
48
+		struct hostent* he,
49
+		unsigned int idx,
50
+		unsigned short port)
51
+{
52
+	memset(su, 0, sizeof(union sockaddr_union)); /*needed on freebsd*/
53
+	su->s.sa_family=he->h_addrtype;
54
+	switch(he->h_addrtype){
55
+		case	AF_INET6:
56
+			memcpy(&su->sin6.sin6_addr, he->h_addr_list[idx], he->h_length);
57
+#ifdef HAVE_SOCKADDR_SA_LEN
58
+			su->sin6.sin6_len=sizeof(struct sockaddr_in6);
59
+#endif
60
+			su->sin6.sin6_port=htons(port);
61
+			break;
62
+		case AF_INET:
63
+			memcpy(&su->sin.sin_addr, he->h_addr_list[idx], he->h_length);
64
+#ifdef HAVE_SOCKADDR_SA_LEN
65
+			su->sin.sin_len=sizeof(struct sockaddr_in);
66
+#endif
67
+			su->sin.sin_port=htons(port);
68
+			break;
69
+		default:
70
+			LM_CRIT("unknown address family %d\n", he->h_addrtype);
71
+			return -1;
72
+	}
73
+	return 0;
74
+}
75
+
76
+
77
+/* converts a raw ipv6 addr (16 bytes) to ascii */
78
+int ip6tosbuf(unsigned char* ip6, char* buff, int len)
79
+{
80
+	int offset;
81
+	register unsigned char a,b,c;
82
+	register unsigned char d;
83
+	register unsigned short hex4;
84
+	int r;
85
+
86
+	if(ksr_ipv6_hex_style.s[0] == 'c') {
87
+		if (inet_ntop(AF_INET6, ip6, buff, len) == NULL) {
88
+			return 0;
89
+		}
90
+		return strlen(buff);
91
+	}
92
+
93
+#define HEXDIG(x) (((x)>=10)?(x)-10+ksr_ipv6_hex_style.s[0]:(x)+'0')
94
+
95
+	offset=0;
96
+	if (unlikely(len<IP6_MAX_STR_SIZE))
97
+		return 0;
98
+	for(r=0;r<7;r++){
99
+		hex4=((unsigned char)ip6[r*2]<<8)+(unsigned char)ip6[r*2+1];
100
+		a=hex4>>12;
101
+		b=(hex4>>8)&0xf;
102
+		c=(hex4>>4)&0xf;
103
+		d=hex4&0xf;
104
+		if (a){
105
+			buff[offset]=HEXDIG(a);
106
+			buff[offset+1]=HEXDIG(b);
107
+			buff[offset+2]=HEXDIG(c);
108
+			buff[offset+3]=HEXDIG(d);
109
+			buff[offset+4]=':';
110
+			offset+=5;
111
+		}else if(b){
112
+			buff[offset]=HEXDIG(b);
113
+			buff[offset+1]=HEXDIG(c);
114
+			buff[offset+2]=HEXDIG(d);
115
+			buff[offset+3]=':';
116
+			offset+=4;
117
+		}else if(c){
118
+			buff[offset]=HEXDIG(c);
119
+			buff[offset+1]=HEXDIG(d);
120
+			buff[offset+2]=':';
121
+			offset+=3;
122
+		}else{
123
+			buff[offset]=HEXDIG(d);
124
+			buff[offset+1]=':';
125
+			offset+=2;
126
+		}
127
+	}
128
+	/* last int16*/
129
+	hex4=((unsigned char)ip6[r*2]<<8)+(unsigned char)ip6[r*2+1];
130
+	a=hex4>>12;
131
+	b=(hex4>>8)&0xf;
132
+	c=(hex4>>4)&0xf;
133
+	d=hex4&0xf;
134
+	if (a){
135
+		buff[offset]=HEXDIG(a);
136
+		buff[offset+1]=HEXDIG(b);
137
+		buff[offset+2]=HEXDIG(c);
138
+		buff[offset+3]=HEXDIG(d);
139
+		offset+=4;
140
+	}else if(b){
141
+		buff[offset]=HEXDIG(b);
142
+		buff[offset+1]=HEXDIG(c);
143
+		buff[offset+2]=HEXDIG(d);
144
+		offset+=3;
145
+	}else if(c){
146
+		buff[offset]=HEXDIG(c);
147
+		buff[offset+1]=HEXDIG(d);
148
+		offset+=2;
149
+	}else{
150
+		buff[offset]=HEXDIG(d);
151
+		offset+=1;
152
+	}
153
+
154
+	return offset;
155
+}
156
+
157
+
158
+/* converts a raw ipv4 addr (4 bytes) to ascii */
159
+int ip4tosbuf(unsigned char* ip4, char* buff, int len)
160
+{
161
+	int offset;
162
+	register unsigned char a,b,c;
163
+	int r;
164
+
165
+	offset=0;
166
+	if (unlikely(len<IP4_MAX_STR_SIZE))
167
+		return 0;
168
+	for(r=0;r<3;r++){
169
+		a=(unsigned char)ip4[r]/100;
170
+		c=(unsigned char)ip4[r]%10;
171
+		b=(unsigned char)ip4[r]%100/10;
172
+		if (a){
173
+			buff[offset]=a+'0';
174
+			buff[offset+1]=b+'0';
175
+			buff[offset+2]=c+'0';
176
+			buff[offset+3]='.';
177
+			offset+=4;
178
+		}else if (b){
179
+			buff[offset]=b+'0';
180
+			buff[offset+1]=c+'0';
181
+			buff[offset+2]='.';
182
+			offset+=3;
183
+		}else{
184
+			buff[offset]=c+'0';
185
+			buff[offset+1]='.';
186
+			offset+=2;
187
+		}
188
+	}
189
+	/* last number */
190
+	a=(unsigned char)ip4[r]/100;
191
+	c=(unsigned char)ip4[r]%10;
192
+	b=(unsigned char)ip4[r]%100/10;
193
+	if (a){
194
+		buff[offset]=a+'0';
195
+		buff[offset+1]=b+'0';
196
+		buff[offset+2]=c+'0';
197
+		offset+=3;
198
+	}else if (b){
199
+		buff[offset]=b+'0';
200
+		buff[offset+1]=c+'0';
201
+		offset+=2;
202
+	}else{
203
+		buff[offset]=c+'0';
204
+		offset+=1;
205
+	}
206
+
207
+	return offset;
208
+}
209
+
210
+
211
+/* fast ip_addr -> string converter;
212
+ * returns number of bytes written in buf on success, <=0 on error
213
+ * The buffer must have enough space to hold the maximum size ip address
214
+ *  of the corresponding address (see IP[46] above) or else the function
215
+ *  will return error (no detailed might fit checks are made, for example
216
+ *   if len==7 the function will fail even for 1.2.3.4).
217
+ */
218
+int ip_addr2sbuf(struct ip_addr* ip, char* buff, int len)
219
+{
220
+	switch(ip->af){
221
+		case AF_INET6:
222
+			return ip6tosbuf(ip->u.addr, buff, len);
223
+			break;
224
+		case AF_INET:
225
+			return ip4tosbuf(ip->u.addr, buff, len);
226
+			break;
227
+		default:
228
+			LM_CRIT("unknown address family %d\n", ip->af);
229
+			return 0;
230
+	}
231
+}
232
+
233
+
234
+/* same as ip_addr2sbuf, but with [  ] around IPv6 addresses */
235
+int ip_addr2sbufz(struct ip_addr* ip, char* buff, int len)
236
+{
237
+	char *p;
238
+	int sz;
239
+
240
+	p = buff;
241
+	switch(ip->af){
242
+		case AF_INET6:
243
+			*p++ = '[';
244
+			sz = ip6tosbuf(ip->u.addr, p, len-2);
245
+			p += sz;
246
+			*p++ = ']';
247
+			*p=0;
248
+			return sz + 2;
249
+			break;
250
+		case AF_INET:
251
+			return ip4tosbuf(ip->u.addr, buff, len);
252
+			break;
253
+		default:
254
+			LM_CRIT("unknown address family %d\n", ip->af);
255
+			return 0;
256
+	}
257
+}
258
+
259
+
260
+/* fast ip_addr -> string converter;
261
+ * it uses an internal buffer
262
+ */
263
+char* ip_addr2a(struct ip_addr* ip)
264
+{
265
+	static char buff[IP_ADDR_MAX_STR_SIZE];
266
+	int len;
267
+
268
+	len=ip_addr2sbuf(ip, buff, sizeof(buff)-1);
269
+	buff[len]=0;
270
+
271
+	return buff;
272
+}
273
+
274
+
275
+/* full address in text representation, including [] for ipv6 */
276
+char* ip_addr2strz(struct ip_addr* ip)
277
+{
278
+
279
+	static char buff[IP_ADDR_MAX_STRZ_SIZE];
280
+	char *p;
281
+	int len;
282
+
283
+	p = buff;
284
+	if(ip->af==AF_INET6) {
285
+		*p++ = '[';
286
+	}
287
+	len=ip_addr2sbuf(ip, p, sizeof(buff)-3);
288
+	p += len;
289
+	if(ip->af==AF_INET6) {
290
+		*p++ = ']';
291
+	}
292
+	*p=0;
293
+
294
+	return buff;
295
+}
296
+
297
+
298
+/* returns an asciiz string containing the ip and the port
299
+ *  (<ip_addr>:port or [<ipv6_addr>]:port)
300
+ */
301
+char* su2a(union sockaddr_union* su, int su_len)
302
+{
303
+	static char buf[SU2A_MAX_STR_SIZE];
304
+	int offs;
305
+
306
+	if (unlikely(su->s.sa_family==AF_INET6)){
307
+		if (unlikely(su_len<sizeof(su->sin6)))
308
+			return "<addr. error>";
309
+		buf[0]='[';
310
+		offs=1+ip6tosbuf((unsigned char*)su->sin6.sin6_addr.s6_addr, &buf[1],
311
+				sizeof(buf)-4);
312
+		buf[offs]=']';
313
+		offs++;
314
+	} else {
315
+		if (unlikely(su_len<sizeof(su->sin)))
316
+			return "<addr. error>";
317
+		else
318
+			offs=ip4tosbuf((unsigned char*)&su->sin.sin_addr, buf, sizeof(buf)-2);
319
+	}
320
+	buf[offs]=':';
321
+	offs+=1+ushort2sbuf(su_getport(su), &buf[offs+1], sizeof(buf)-(offs+1)-1);
322
+	buf[offs]=0;
323
+	return buf;
324
+}
325
+
326
+
327
+/* returns an asciiz string containing the ip
328
+ *  (<ipv4_addr> or [<ipv6_addr>])
329
+ */
330
+char* suip2a(union sockaddr_union* su, int su_len)
331
+{
332
+	static char buf[SUIP2A_MAX_STR_SIZE];
333
+	int offs;
334
+
335
+	if (unlikely(su->s.sa_family==AF_INET6)){
336
+		if (unlikely(su_len<sizeof(su->sin6)))
337
+			return "<addr. error>";
338
+		buf[0]='[';
339
+		offs=1+ip6tosbuf((unsigned char*)su->sin6.sin6_addr.s6_addr, &buf[1],
340
+				IP6_MAX_STR_SIZE);
341
+		buf[offs]=']';
342
+		offs++;
343
+	}else
344
+		if (unlikely(su_len<sizeof(su->sin)))
345
+			return "<addr. error>";
346
+		else
347
+			offs=ip4tosbuf((unsigned char*)&su->sin.sin_addr, buf, IP4_MAX_STR_SIZE);
348
+	buf[offs]=0;
349
+	return buf;
350
+}
351
+
352
+
353
+/* converts an ip_addr structure to a hostent, returns pointer to internal
354
+ * statical structure */
355
+struct hostent* ip_addr2he(str* name, struct ip_addr* ip)
356
+{
357
+	static struct hostent he;
358
+	static char hostname[256];
359
+	static char* p_aliases[1];
360
+	static char* p_addr[2];
361
+	static char address[16];
362
+	int len;
363
+
364
+	p_aliases[0]=0; /* no aliases*/
365
+	p_addr[1]=0; /* only one address*/
366
+	p_addr[0]=address;
367
+	len = (name->len<255)?name->len:255;
368
+	memcpy(hostname, name->s, len);
369
+	hostname[len] = '\0';
370
+	if (ip->len>16) return 0;
371
+	memcpy(address, ip->u.addr, ip->len);
372
+
373
+	he.h_addrtype=ip->af;
374
+	he.h_length=ip->len;
375
+	he.h_addr_list=p_addr;
376
+	he.h_aliases=p_aliases;
377
+	he.h_name=hostname;
378
+	return &he;
379
+}
380
+
40 381
 
41 382
 struct net* mk_new_net(struct ip_addr* ip, struct ip_addr* mask)
42 383
 {
43 384
 	struct net* n;
44 385
 	int warning;
45 386
 	int r;
46
-	
387
+
47 388
 	warning=0;
48 389
 	if ((ip->af != mask->af) || (ip->len != mask->len)){
49 390
 		LM_CRIT("trying to use a different mask family"
... ...
@@ -51,7 +392,7 @@ struct net* mk_new_net(struct ip_addr* ip, struct ip_addr* mask)
51 392
 		goto error;
52 393
 	}
53 394
 	n=(struct net*)pkg_malloc(sizeof(struct net));
54
-	if (n==0){ 
395
+	if (n==0){
55 396
 		PKG_MEM_CRITICAL;
56 397
 		goto error;
57 398
 	}
... ...
@@ -80,7 +421,7 @@ struct net* mk_new_net_bitlen(struct ip_addr* ip, unsigned int bitlen)
80 421
 {
81 422
 	struct ip_addr mask;
82 423
 	int r;
83
-	
424
+
84 425
 	if (bitlen>ip->len*8){
85 426
 		LM_CRIT("bad bitlen number %d\n", bitlen);
86 427
 		goto error;
... ...
@@ -90,7 +431,7 @@ struct net* mk_new_net_bitlen(struct ip_addr* ip, unsigned int bitlen)
90 431
 	if (bitlen%8) mask.u.addr[r]=  ~((1<<(8-(bitlen%8)))-1);
91 432
 	mask.af=ip->af;
92 433
 	mask.len=ip->len;
93
-	
434
+
94 435
 	return mk_new_net(ip, &mask);
95 436
 error:
96 437
 	return 0;
... ...
@@ -111,7 +452,7 @@ error:
111 452
 int mk_net(struct net* n, struct ip_addr* ip, struct ip_addr* mask)
112 453
 {
113 454
 	int r;
114
-	
455
+
115 456
 	if (unlikely((ip->af != mask->af) || (ip->len != mask->len))) {
116 457
 		return -1;
117 458
 	}
... ...
@@ -140,7 +481,7 @@ int mk_net_bitlen(struct net* n, struct ip_addr* ip, unsigned int bitlen)
140 481
 {
141 482
 	struct ip_addr mask;
142 483
 	int r;
143
-	
484
+
144 485
 	if (unlikely(bitlen>ip->len*8))
145 486
 		/* bitlen too big */
146 487
 		return -1;
... ...
@@ -149,7 +490,7 @@ int mk_net_bitlen(struct net* n, struct ip_addr* ip, unsigned int bitlen)
149 490
 	if (bitlen%8) mask.u.addr[r]=  ~((1<<(8-(bitlen%8)))-1);
150 491
 	mask.af=ip->af;
151 492
 	mask.len=ip->len;
152
-	
493
+
153 494
 	return mk_net(n, ip, &mask);
154 495
 }
155 496
 
... ...
@@ -168,7 +509,7 @@ int mk_net_str(struct net* dst, str* s)
168 509
 	str addr;
169 510
 	str mask;
170 511
 	unsigned int bitlen;
171
-	
512
+
172 513
 	/* test for ip only */
173 514
 	t = str2ip(s);
174 515
 	if (unlikely(t == 0))
... ...
@@ -41,7 +41,7 @@
41 41
 
42 42
 #include "dprint.h"
43 43
 
44
-extern char *ksr_ipv6_hex_style;
44
+extern str ksr_ipv6_hex_style;
45 45
 
46 46
 enum sip_protos { PROTO_NONE, PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_SCTP,
47 47
 	PROTO_WS, PROTO_WSS, PROTO_OTHER };
... ...
@@ -489,34 +489,10 @@ static inline int init_su( union sockaddr_union* su,
489 489
  * the hostent structure and a port no. (host byte order)
490 490
  * WARNING: no index overflow  checks!
491 491
  * returns 0 if ok, -1 on error (unknown address family) */
492
-static inline int hostent2su( union sockaddr_union* su,
492
+int hostent2su(union sockaddr_union* su,
493 493
 		struct hostent* he,
494 494
 		unsigned int idx,
495
-		unsigned short port )
496
-{
497
-	memset(su, 0, sizeof(union sockaddr_union)); /*needed on freebsd*/
498
-	su->s.sa_family=he->h_addrtype;
499
-	switch(he->h_addrtype){
500
-		case	AF_INET6:
501
-			memcpy(&su->sin6.sin6_addr, he->h_addr_list[idx], he->h_length);
502
-#ifdef HAVE_SOCKADDR_SA_LEN
503
-			su->sin6.sin6_len=sizeof(struct sockaddr_in6);
504
-#endif
505
-			su->sin6.sin6_port=htons(port);
506
-			break;
507
-		case AF_INET:
508
-			memcpy(&su->sin.sin_addr, he->h_addr_list[idx], he->h_length);
509
-#ifdef HAVE_SOCKADDR_SA_LEN
510
-			su->sin.sin_len=sizeof(struct sockaddr_in);
511
-#endif
512
-			su->sin.sin_port=htons(port);
513
-			break;
514
-		default:
515
-			LM_CRIT("unknown address family %d\n", he->h_addrtype);
516
-			return -1;
517
-	}
518
-	return 0;
519
-}
495
+		unsigned short port);
520 496
 
521 497
 
522 498
 /* maximum size of a str returned by ip_addr2str */
... ...
@@ -524,130 +500,11 @@ static inline int hostent2su( union sockaddr_union* su,
524 500
 #define IP4_MAX_STR_SIZE 15 /*123.456.789.012*/
525 501
 
526 502
 /* converts a raw ipv6 addr (16 bytes) to ascii */
527
-static inline int ip6tosbuf(unsigned char* ip6, char* buff, int len)
528
-{
529
-	int offset;
530
-	register unsigned char a,b,c;
531
-	register unsigned char d;
532
-	register unsigned short hex4;
533
-	int r;
534
-
535
-#define HEXDIG(x) (((x)>=10)?(x)-10+ksr_ipv6_hex_style[0]:(x)+'0')
536
-
537
-	offset=0;
538
-	if (unlikely(len<IP6_MAX_STR_SIZE))
539
-		return 0;
540
-	for(r=0;r<7;r++){
541
-		hex4=((unsigned char)ip6[r*2]<<8)+(unsigned char)ip6[r*2+1];
542
-		a=hex4>>12;
543
-		b=(hex4>>8)&0xf;
544
-		c=(hex4>>4)&0xf;
545
-		d=hex4&0xf;
546
-		if (a){
547
-			buff[offset]=HEXDIG(a);
548
-			buff[offset+1]=HEXDIG(b);
549
-			buff[offset+2]=HEXDIG(c);
550
-			buff[offset+3]=HEXDIG(d);
551
-			buff[offset+4]=':';
552
-			offset+=5;
553
-		}else if(b){
554
-			buff[offset]=HEXDIG(b);
555
-			buff[offset+1]=HEXDIG(c);
556
-			buff[offset+2]=HEXDIG(d);
557
-			buff[offset+3]=':';
558
-			offset+=4;
559
-		}else if(c){
560
-			buff[offset]=HEXDIG(c);
561
-			buff[offset+1]=HEXDIG(d);
562
-			buff[offset+2]=':';
563
-			offset+=3;
564
-		}else{
565
-			buff[offset]=HEXDIG(d);
566
-			buff[offset+1]=':';
567
-			offset+=2;
568
-		}
569
-	}
570
-	/* last int16*/
571
-	hex4=((unsigned char)ip6[r*2]<<8)+(unsigned char)ip6[r*2+1];
572
-	a=hex4>>12;
573
-	b=(hex4>>8)&0xf;
574
-	c=(hex4>>4)&0xf;
575
-	d=hex4&0xf;
576
-	if (a){
577
-		buff[offset]=HEXDIG(a);
578
-		buff[offset+1]=HEXDIG(b);
579
-		buff[offset+2]=HEXDIG(c);
580
-		buff[offset+3]=HEXDIG(d);
581
-		offset+=4;
582
-	}else if(b){
583
-		buff[offset]=HEXDIG(b);
584
-		buff[offset+1]=HEXDIG(c);
585
-		buff[offset+2]=HEXDIG(d);
586
-		offset+=3;
587
-	}else if(c){
588
-		buff[offset]=HEXDIG(c);
589
-		buff[offset+1]=HEXDIG(d);
590
-		offset+=2;
591
-	}else{
592
-		buff[offset]=HEXDIG(d);
593
-		offset+=1;
594
-	}
595
-
596
-	return offset;
597
-}
503
+int ip6tosbuf(unsigned char* ip6, char* buff, int len);
598 504
 
599 505
 
600 506
 /* converts a raw ipv4 addr (4 bytes) to ascii */
601
-static inline int ip4tosbuf(unsigned char* ip4, char* buff, int len)
602
-{
603
-	int offset;
604
-	register unsigned char a,b,c;
605
-	int r;
606
-
607
-	offset=0;
608
-	if (unlikely(len<IP4_MAX_STR_SIZE))
609
-		return 0;
610
-	for(r=0;r<3;r++){
611
-		a=(unsigned char)ip4[r]/100;
612
-		c=(unsigned char)ip4[r]%10;
613
-		b=(unsigned char)ip4[r]%100/10;
614
-		if (a){
615
-			buff[offset]=a+'0';
616
-			buff[offset+1]=b+'0';
617
-			buff[offset+2]=c+'0';
618
-			buff[offset+3]='.';
619
-			offset+=4;
620
-		}else if (b){
621
-			buff[offset]=b+'0';
622
-			buff[offset+1]=c+'0';
623
-			buff[offset+2]='.';
624
-			offset+=3;
625
-		}else{
626
-			buff[offset]=c+'0';
627
-			buff[offset+1]='.';
628
-			offset+=2;
629
-		}
630
-	}
631
-	/* last number */
632
-	a=(unsigned char)ip4[r]/100;
633
-	c=(unsigned char)ip4[r]%10;
634
-	b=(unsigned char)ip4[r]%100/10;
635
-	if (a){
636
-		buff[offset]=a+'0';
637
-		buff[offset+1]=b+'0';
638
-		buff[offset+2]=c+'0';
639
-		offset+=3;
640
-	}else if (b){
641
-		buff[offset]=b+'0';
642
-		buff[offset+1]=c+'0';
643
-		offset+=2;
644
-	}else{
645
-		buff[offset]=c+'0';
646
-		offset+=1;
647
-	}
648
-
649
-	return offset;
650
-}
507
+int ip4tosbuf(unsigned char* ip4, char* buff, int len);
651 508
 
652 509
 
653 510
 /* fast ip_addr -> string converter;
... ...
@@ -657,170 +514,47 @@ static inline int ip4tosbuf(unsigned char* ip4, char* buff, int len)
657 514
  *  will return error (no detailed might fit checks are made, for example
658 515
  *   if len==7 the function will fail even for 1.2.3.4).
659 516
  */
660
-static inline int ip_addr2sbuf(struct ip_addr* ip, char* buff, int len)
661
-{
662
-	switch(ip->af){
663
-		case AF_INET6:
664
-			return ip6tosbuf(ip->u.addr, buff, len);
665
-			break;
666
-		case AF_INET:
667
-			return ip4tosbuf(ip->u.addr, buff, len);
668
-			break;
669
-		default:
670
-			LM_CRIT("unknown address family %d\n", ip->af);
671
-			return 0;
672
-	}
673
-}
517
+int ip_addr2sbuf(struct ip_addr* ip, char* buff, int len);
518
+
674 519
 
675 520
 /* same as ip_addr2sbuf, but with [  ] around IPv6 addresses */
676
-static inline int ip_addr2sbufz(struct ip_addr* ip, char* buff, int len)
677
-{
678
-	char *p;
679
-	int sz;
521
+int ip_addr2sbufz(struct ip_addr* ip, char* buff, int len);
680 522
 
681
-	p = buff;
682
-	switch(ip->af){
683
-		case AF_INET6:
684
-			*p++ = '[';
685
-			sz = ip6tosbuf(ip->u.addr, p, len-2);
686
-			p += sz;
687
-			*p++ = ']';
688
-			*p=0;
689
-			return sz + 2;
690
-			break;
691
-		case AF_INET:
692
-			return ip4tosbuf(ip->u.addr, buff, len);
693
-			break;
694
-		default:
695
-			LM_CRIT("unknown address family %d\n", ip->af);
696
-			return 0;
697
-	}
698
-}
699 523
 
700 524
 /* maximum size of a str returned by ip_addr2a (including \0) */
701 525
 #define IP_ADDR_MAX_STR_SIZE (IP6_MAX_STR_SIZE+1) /* ip62ascii +  \0*/
702 526
 #define IP_ADDR_MAX_STRZ_SIZE (IP6_MAX_STR_SIZE+3) /* ip62ascii + [ + ] + \0*/
527
+
703 528
 /* fast ip_addr -> string converter;
704 529
  * it uses an internal buffer
705 530
  */
706
-static inline char* ip_addr2a(struct ip_addr* ip)
707
-{
708
-	static char buff[IP_ADDR_MAX_STR_SIZE];
709
-	int len;
710
-
711
-	len=ip_addr2sbuf(ip, buff, sizeof(buff)-1);
712
-	buff[len]=0;
713
-
714
-	return buff;
715
-}
531
+char* ip_addr2a(struct ip_addr* ip);
716 532
 
717 533
 
718 534
 /* full address in text representation, including [] for ipv6 */
719
-static inline char* ip_addr2strz(struct ip_addr* ip)
720
-{
535
+char* ip_addr2strz(struct ip_addr* ip);
721 536
 
722
-	static char buff[IP_ADDR_MAX_STRZ_SIZE];
723
-	char *p;
724
-	int len;
725
-
726
-	p = buff;
727
-	if(ip->af==AF_INET6) {
728
-		*p++ = '[';
729
-	}
730
-	len=ip_addr2sbuf(ip, p, sizeof(buff)-3);
731
-	p += len;
732
-	if(ip->af==AF_INET6) {
733
-		*p++ = ']';
734
-	}
735
-	*p=0;
736
-
737
-	return buff;
738
-}
739 537
 
740 538
 #define SU2A_MAX_STR_SIZE  (IP6_MAX_STR_SIZE + 2 /* [] */+\
741 539
 		1 /* : */ + USHORT2SBUF_MAX_LEN + 1 /* \0 */)
742 540
 
541
+
743 542
 /* returns an asciiz string containing the ip and the port
744 543
  *  (<ip_addr>:port or [<ipv6_addr>]:port)
745 544
  */
746
-static inline char* su2a(union sockaddr_union* su, int su_len)
747
-{
748
-	static char buf[SU2A_MAX_STR_SIZE];
749
-	int offs;
750
-
751
-	if (unlikely(su->s.sa_family==AF_INET6)){
752
-		if (unlikely(su_len<sizeof(su->sin6)))
753
-			return "<addr. error>";
754
-		buf[0]='[';
755
-		offs=1+ip6tosbuf((unsigned char*)su->sin6.sin6_addr.s6_addr, &buf[1],
756
-				sizeof(buf)-4);
757
-		buf[offs]=']';
758
-		offs++;
759
-	}else
760
-		if (unlikely(su_len<sizeof(su->sin)))
761
-			return "<addr. error>";
762
-		else
763
-			offs=ip4tosbuf((unsigned char*)&su->sin.sin_addr, buf, sizeof(buf)-2);
764
-	buf[offs]=':';
765
-	offs+=1+ushort2sbuf(su_getport(su), &buf[offs+1], sizeof(buf)-(offs+1)-1);
766
-	buf[offs]=0;
767
-	return buf;
768
-}
545
+char* su2a(union sockaddr_union* su, int su_len);
769 546
 
770 547
 #define SUIP2A_MAX_STR_SIZE  (IP6_MAX_STR_SIZE + 2 /* [] */ + 1 /* \0 */)
548
+
771 549
 /* returns an asciiz string containing the ip
772 550
  *  (<ipv4_addr> or [<ipv6_addr>])
773 551
  */
774
-static inline char* suip2a(union sockaddr_union* su, int su_len)
775
-{
776
-	static char buf[SUIP2A_MAX_STR_SIZE];
777
-	int offs;
778
-
779
-	if (unlikely(su->s.sa_family==AF_INET6)){
780
-		if (unlikely(su_len<sizeof(su->sin6)))
781
-			return "<addr. error>";
782
-		buf[0]='[';
783
-		offs=1+ip6tosbuf((unsigned char*)su->sin6.sin6_addr.s6_addr, &buf[1],
784
-				IP6_MAX_STR_SIZE);
785
-		buf[offs]=']';
786
-		offs++;
787
-	}else
788
-		if (unlikely(su_len<sizeof(su->sin)))
789
-			return "<addr. error>";
790
-		else
791
-			offs=ip4tosbuf((unsigned char*)&su->sin.sin_addr, buf, IP4_MAX_STR_SIZE);
792
-	buf[offs]=0;
793
-	return buf;
794
-}
552
+char* suip2a(union sockaddr_union* su, int su_len);
795 553
 
796 554
 
797 555
 /* converts an ip_addr structure to a hostent, returns pointer to internal
798 556
  * statical structure */
799
-static inline struct hostent* ip_addr2he(str* name, struct ip_addr* ip)
800
-{
801
-	static struct hostent he;
802
-	static char hostname[256];
803
-	static char* p_aliases[1];
804
-	static char* p_addr[2];
805
-	static char address[16];
806
-	int len;
807
-
808
-	p_aliases[0]=0; /* no aliases*/
809
-	p_addr[1]=0; /* only one address*/
810
-	p_addr[0]=address;
811
-	len = (name->len<255)?name->len:255;
812
-	memcpy(hostname, name->s, len);
813
-	hostname[len] = '\0';
814
-	if (ip->len>16) return 0;
815
-	memcpy(address, ip->u.addr, ip->len);
816
-
817
-	he.h_addrtype=ip->af;
818
-	he.h_length=ip->len;
819
-	he.h_addr_list=p_addr;
820
-	he.h_aliases=p_aliases;
821
-	he.h_name=hostname;
822
-	return &he;
823
-}
557
+struct hostent* ip_addr2he(str* name, struct ip_addr* ip);
824 558
 
825 559
 
826 560
 /* init a dest_info structure */