Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,4820 +0,0 @@
1
-/*
2
- * Copyright (C) 2001-2003 FhG Fokus
3
- *
4
- * This file is part of Kamailio, a free SIP server.
5
- *
6
- * Kamailio is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version
10
- *
11
- * Kamailio is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program; if not, write to the Free Software
18
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19
- */
20
-
21
-/** Kamailio core: tcp main/dispatcher and tcp send functions.
22
- * @file tcp_main.c
23
- * @ingroup core
24
- * Module: @ref core
25
- */
26
-
27
-
28
-#ifdef USE_TCP
29
-
30
-
31
-#ifndef SHM_MEM
32
-#error "shared memory support needed (add -DSHM_MEM to Makefile.defs)"
33
-#endif
34
-
35
-#define HANDLE_IO_INLINE
36
-#include "io_wait.h" /* include first to make sure the needed features are
37
-						turned on (e.g. _GNU_SOURCE for POLLRDHUP) */
38
-
39
-#include <sys/time.h>
40
-#include <sys/types.h>
41
-#include <sys/select.h>
42
-#include <sys/socket.h>
43
-#ifdef HAVE_FILIO_H
44
-#include <sys/filio.h> /* needed on solaris 2.x for FIONREAD */
45
-#elif defined __OS_solaris
46
-#define BSD_COMP  /* needed on older solaris for FIONREAD */
47
-#endif /* HAVE_FILIO_H / __OS_solaris */
48
-#include <sys/ioctl.h>  /* ioctl() used on write error */
49
-#include <netinet/in.h>
50
-#include <netinet/in_systm.h>
51
-#include <netinet/ip.h>
52
-#include <netinet/tcp.h>
53
-#include <sys/uio.h>  /* writev*/
54
-#include <netdb.h>
55
-#include <stdlib.h> /*exit() */
56
-
57
-#include <unistd.h>
58
-
59
-#include <errno.h>
60
-#include <string.h>
61
-
62
-#ifdef HAVE_SELECT
63
-#include <sys/select.h>
64
-#endif
65
-#include <poll.h>
66
-
67
-
68
-#include "ip_addr.h"
69
-#include "pass_fd.h"
70
-#include "tcp_conn.h"
71
-#include "globals.h"
72
-#include "pt.h"
73
-#include "locking.h"
74
-#include "mem/mem.h"
75
-#include "mem/shm_mem.h"
76
-#include "timer.h"
77
-#include "sr_module.h"
78
-#include "tcp_server.h"
79
-#include "tcp_init.h"
80
-#include "tcp_int_send.h"
81
-#include "tcp_stats.h"
82
-#include "tcp_ev.h"
83
-#include "tsend.h"
84
-#include "timer_ticks.h"
85
-#include "local_timer.h"
86
-#ifdef CORE_TLS
87
-#include "tls/tls_server.h"
88
-#define tls_loaded() 1
89
-#else
90
-#include "tls_hooks_init.h"
91
-#include "tls_hooks.h"
92
-#endif /* CORE_TLS*/
93
-#ifdef USE_DST_BLACKLIST
94
-#include "dst_blacklist.h"
95
-#endif /* USE_DST_BLACKLIST */
96
-
97
-#include "tcp_info.h"
98
-#include "tcp_options.h"
99
-#include "ut.h"
100
-#include "cfg/cfg_struct.h"
101
-
102
-#define local_malloc pkg_malloc
103
-#define local_free   pkg_free
104
-
105
-#include <fcntl.h> /* must be included after io_wait.h if SIGIO_RT is used */
106
-
107
-
108
-#ifdef NO_MSG_DONTWAIT
109
-#ifndef MSG_DONTWAIT
110
-/* should work inside tcp_main */
111
-#define MSG_DONTWAIT 0
112
-#endif
113
-#endif /*NO_MSG_DONTWAIT */
114
-
115
-
116
-#define TCP_PASS_NEW_CONNECTION_ON_DATA /* don't pass a new connection
117
-										   immediately to a child, wait for
118
-										   some data on it first */
119
-#define TCP_LISTEN_BACKLOG 1024
120
-#define SEND_FD_QUEUE /* queue send fd requests on EAGAIN, instead of sending 
121
-							them immediately */
122
-#define TCP_CHILD_NON_BLOCKING 
123
-#ifdef SEND_FD_QUEUE
124
-#ifndef TCP_CHILD_NON_BLOCKING
125
-#define TCP_CHILD_NON_BLOCKING
126
-#endif
127
-#define MAX_SEND_FD_QUEUE_SIZE	tcp_main_max_fd_no
128
-#define SEND_FD_QUEUE_SIZE		128  /* initial size */
129
-#define SEND_FD_QUEUE_TIMEOUT	MS_TO_TICKS(2000)  /* 2 s */
130
-#endif
131
-
132
-/* minimum interval local_timer_run() is allowed to run, in ticks */
133
-#define TCPCONN_TIMEOUT_MIN_RUN 1  /* once per tick */
134
-#define TCPCONN_WAIT_TIMEOUT 1 /* 1 tick */
135
-
136
-#ifdef TCP_ASYNC
137
-static unsigned int* tcp_total_wq=0;
138
-#endif
139
-
140
-
141
-enum fd_types { F_NONE, F_SOCKINFO /* a tcp_listen fd */,
142
-				F_TCPCONN, F_TCPCHILD, F_PROC };
143
-
144
-
145
-#ifdef TCP_FD_CACHE
146
-
147
-#define TCP_FD_CACHE_SIZE 8
148
-
149
-struct fd_cache_entry{
150
-	struct tcp_connection* con;
151
-	int id;
152
-	int fd;
153
-};
154
-
155
-
156
-static struct fd_cache_entry fd_cache[TCP_FD_CACHE_SIZE];
157
-#endif /* TCP_FD_CACHE */
158
-
159
-static int is_tcp_main=0;
160
-
161
-
162
-enum poll_types tcp_poll_method=0; /* by default choose the best method */
163
-int tcp_main_max_fd_no=0;
164
-int tcp_max_connections=DEFAULT_TCP_MAX_CONNECTIONS;
165
-int tls_max_connections=DEFAULT_TLS_MAX_CONNECTIONS;
166
-
167
-static union sockaddr_union tcp_source_ipv4_addr; /* saved bind/srv v4 addr. */
168
-static union sockaddr_union* tcp_source_ipv4=0;
169
-static union sockaddr_union tcp_source_ipv6_addr; /* saved bind/src v6 addr. */
170
-static union sockaddr_union* tcp_source_ipv6=0;
171
-
172
-static int* tcp_connections_no=0; /* current tcp (+tls) open connections */
173
-static int* tls_connections_no=0; /* current tls open connections */
174
-
175
-/* connection hash table (after ip&port) , includes also aliases */
176
-struct tcp_conn_alias** tcpconn_aliases_hash=0;
177
-/* connection hash table (after connection id) */
178
-struct tcp_connection** tcpconn_id_hash=0;
179
-gen_lock_t* tcpconn_lock=0;
180
-
181
-struct tcp_child* tcp_children=0;
182
-static int* connection_id=0; /*  unique for each connection, used for 
183
-								quickly finding the corresponding connection
184
-								for a reply */
185
-int unix_tcp_sock;
186
-
187
-static int tcp_proto_no=-1; /* tcp protocol number as returned by
188
-							   getprotobyname */
189
-
190
-static io_wait_h io_h;
191
-
192
-static struct local_timer tcp_main_ltimer;
193
-static ticks_t tcp_main_prev_ticks;
194
-
195
-/* tell if there are tcp workers that should handle only specific socket
196
- * - used to optimize the search of least loaded worker for a tcp socket
197
- * - 0 - no workers per tcp sockets have been set
198
- * - 1 + generic_workers - when there are workers per tcp sockets
199
- */
200
-static int tcp_sockets_gworkers = 0;
201
-
202
-static ticks_t tcpconn_main_timeout(ticks_t , struct timer_ln* , void* );
203
-
204
-inline static int _tcpconn_add_alias_unsafe(struct tcp_connection* c, int port,
205
-										struct ip_addr* l_ip, int l_port,
206
-										int flags);
207
-
208
-
209
-
210
-/* sets source address used when opening new sockets and no source is specified
211
- *  (by default the address is choosen by the kernel)
212
- * Should be used only on init.
213
- * returns -1 on error */
214
-int tcp_set_src_addr(struct ip_addr* ip)
215
-{
216
-	switch (ip->af){
217
-		case AF_INET:
218
-			ip_addr2su(&tcp_source_ipv4_addr, ip, 0);
219
-			tcp_source_ipv4=&tcp_source_ipv4_addr;
220
-			break;
221
-		case AF_INET6:
222
-			ip_addr2su(&tcp_source_ipv6_addr, ip, 0);
223
-			tcp_source_ipv6=&tcp_source_ipv6_addr;
224
-			break;
225
-		default:
226
-			return -1;
227
-	}
228
-	return 0;
229
-}
230
-
231
-
232
-
233
-static inline int init_sock_keepalive(int s)
234
-{
235
-	int optval;
236
-	
237
-#ifdef HAVE_SO_KEEPALIVE
238
-	if (cfg_get(tcp, tcp_cfg, keepalive)){
239
-		optval=1;
240
-		if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval,
241
-						sizeof(optval))<0){
242
-			LM_WARN("failed to enable SO_KEEPALIVE: %s\n", strerror(errno));
243
-			return -1;
244
-		}
245
-	}
246
-#endif
247
-#ifdef HAVE_TCP_KEEPINTVL
248
-	if ((optval=cfg_get(tcp, tcp_cfg, keepintvl))){
249
-		if (setsockopt(s, IPPROTO_TCP, TCP_KEEPINTVL, &optval,
250
-						sizeof(optval))<0){
251
-			LM_WARN("failed to set keepalive probes interval: %s\n", strerror(errno));
252
-		}
253
-	}
254
-#endif
255
-#ifdef HAVE_TCP_KEEPIDLE
256
-	if ((optval=cfg_get(tcp, tcp_cfg, keepidle))){
257
-		if (setsockopt(s, IPPROTO_TCP, TCP_KEEPIDLE, &optval,
258
-						sizeof(optval))<0){
259
-			LM_WARN("failed to set keepalive idle interval: %s\n", strerror(errno));
260
-		}
261
-	}
262
-#endif
263
-#ifdef HAVE_TCP_KEEPCNT
264
-	if ((optval=cfg_get(tcp, tcp_cfg, keepcnt))){
265
-		if (setsockopt(s, IPPROTO_TCP, TCP_KEEPCNT, &optval,
266
-						sizeof(optval))<0){
267
-			LM_WARN("failed to set maximum keepalive count: %s\n", strerror(errno));
268
-		}
269
-	}
270
-#endif
271
-	return 0;
272
-}
273
-
274
-
275
-
276
-/* set all socket/fd options for new sockets (e.g. before connect): 
277
- *  disable nagle, tos lowdelay, reuseaddr, non-blocking
278
- *
279
- * return -1 on error */
280
-static int init_sock_opt(int s, int af)
281
-{
282
-	int flags;
283
-	int optval;
284
-	
285
-#ifdef DISABLE_NAGLE
286
-	flags=1;
287
-	if ( (tcp_proto_no!=-1) && (setsockopt(s, tcp_proto_no , TCP_NODELAY,
288
-					&flags, sizeof(flags))<0) ){
289
-		LM_WARN("could not disable Nagle: %s\n", strerror(errno));
290
-	}
291
-#endif
292
-	/* tos*/
293
-	optval = tos;
294
-	if(af==AF_INET){
295
-		if (setsockopt(s, IPPROTO_IP, IP_TOS, (void*)&optval,
296
-					sizeof(optval)) ==-1){
297
-			LM_WARN("setsockopt tos: %s\n", strerror(errno));
298
-			/* continue since this is not critical */
299
-		}
300
-	} else if(af==AF_INET6){
301
-		if (setsockopt(s, IPPROTO_IPV6, IPV6_TCLASS,
302
-					(void*)&optval, sizeof(optval)) ==-1) {
303
-			LM_WARN("setsockopt v6 tos: %s\n", strerror(errno));
304
-			/* continue since this is not critical */
305
-		}
306
-	}
307
-
308
-#if  !defined(TCP_DONT_REUSEADDR) 
309
-	optval=1;
310
-	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
311
-						(void*)&optval, sizeof(optval))==-1){
312
-		LM_ERR("setsockopt SO_REUSEADDR %s\n", strerror(errno));
313
-		/* continue, not critical */
314
-	}
315
-#endif /* !TCP_DONT_REUSEADDR */
316
-#ifdef HAVE_TCP_SYNCNT
317
-	if ((optval=cfg_get(tcp, tcp_cfg, syncnt))){
318
-		if (setsockopt(s, IPPROTO_TCP, TCP_SYNCNT, &optval,
319
-						sizeof(optval))<0){
320
-			LM_WARN("failed to set maximum SYN retr. count: %s\n", strerror(errno));
321
-		}
322
-	}
323
-#endif
324
-#ifdef HAVE_TCP_LINGER2
325
-	if ((optval=cfg_get(tcp, tcp_cfg, linger2))){
326
-		if (setsockopt(s, IPPROTO_TCP, TCP_LINGER2, &optval,
327
-						sizeof(optval))<0){
328
-			LM_WARN("failed to set maximum LINGER2 timeout: %s\n", strerror(errno));
329
-		}
330
-	}
331
-#endif
332
-#ifdef HAVE_TCP_QUICKACK
333
-	if (cfg_get(tcp, tcp_cfg, delayed_ack)){
334
-		optval=0; /* reset quick ack => delayed ack */
335
-		if (setsockopt(s, IPPROTO_TCP, TCP_QUICKACK, &optval,
336
-						sizeof(optval))<0){
337
-			LM_WARN("failed to reset TCP_QUICKACK: %s\n", strerror(errno));
338
-		}
339
-	}
340
-#endif /* HAVE_TCP_QUICKACK */
341
-	init_sock_keepalive(s);
342
-	
343
-	/* non-blocking */
344
-	flags=fcntl(s, F_GETFL);
345
-	if (flags==-1){
346
-		LM_ERR("fnctl failed: (%d) %s\n", errno, strerror(errno));
347
-		goto error;
348
-	}
349
-	if (fcntl(s, F_SETFL, flags|O_NONBLOCK)==-1){
350
-		LM_ERR("fcntl: set non-blocking failed: (%d) %s\n", errno, strerror(errno));
351
-		goto error;
352
-	}
353
-	return 0;
354
-error:
355
-	return -1;
356
-}
357
-
358
-
359
-
360
-/* set all socket/fd options for "accepted" sockets 
361
- *  only nonblocking is set since the rest is inherited from the
362
- *  "parent" (listening) socket
363
- *  Note: setting O_NONBLOCK is required on linux but it's not needed on
364
- *        BSD and possibly solaris (where the flag is inherited from the 
365
- *        parent socket). However since there is no standard document 
366
- *        requiring a specific behaviour in this case it's safer to always set
367
- *        it (at least for now)  --andrei
368
- *  TODO: check on which OSes  O_NONBLOCK is inherited and make this 
369
- *        function a nop.
370
- *
371
- * return -1 on error */
372
-static int init_sock_opt_accept(int s)
373
-{
374
-	int flags;
375
-	
376
-	/* non-blocking */
377
-	flags=fcntl(s, F_GETFL);
378
-	if (flags==-1){
379
-		LM_ERR("fnctl failed: (%d) %s\n", errno, strerror(errno));
380
-		goto error;
381
-	}
382
-	if (fcntl(s, F_SETFL, flags|O_NONBLOCK)==-1){
383
-		LM_ERR("fcntl: set non-blocking failed: (%d) %s\n", errno, strerror(errno));
384
-		goto error;
385
-	}
386
-	return 0;
387
-error:
388
-	return -1;
389
-}
390
-
391
-
392
-
393
-/** close a socket, handling errno.
394
- * On EINTR, repeat the close().
395
- * Filter expected errors (return success if close() failed because
396
- * EPIPE, ECONNRST a.s.o). Note that this happens on *BSDs (on linux close()
397
- * does not fail for socket level errors).
398
- * @param s - open valid socket.
399
- * @return - 0 on success, < 0 on error (whatever close() returns). On error
400
- *           errno is set.
401
- */
402
-static int tcp_safe_close(int s)
403
-{
404
-	int ret;
405
-retry:
406
-	if (unlikely((ret = close(s)) < 0 )) {
407
-		switch(errno) {
408
-			case EINTR:
409
-				goto retry;
410
-			case EPIPE:
411
-			case ENOTCONN:
412
-			case ECONNRESET:
413
-			case ECONNREFUSED:
414
-			case ENETUNREACH:
415
-			case EHOSTUNREACH:
416
-				/* on *BSD we really get these errors at close() time 
417
-				   => ignore them */
418
-				ret = 0;
419
-				break;
420
-			default:
421
-				break;
422
-		}
423
-	}
424
-	return ret;
425
-}
426
-
427
-
428
-
429
-/* blocking connect on a non-blocking fd; it will timeout after
430
- * tcp_connect_timeout 
431
- * if BLOCKING_USE_SELECT and HAVE_SELECT are defined it will internally
432
- * use select() instead of poll (bad if fd > FD_SET_SIZE, poll is preferred)
433
- */
434
-static int tcp_blocking_connect(int fd, int type, snd_flags_t* send_flags,
435
-								const struct sockaddr *servaddr,
436
-								socklen_t addrlen)
437
-{
438
-	int n;
439
-#if defined(HAVE_SELECT) && defined(BLOCKING_USE_SELECT)
440
-	fd_set sel_set;
441
-	fd_set orig_set;
442
-	struct timeval timeout;
443
-#else
444
-	struct pollfd pf;
445
-#endif
446
-	int elapsed;
447
-	int to;
448
-	int ticks;
449
-	int err;
450
-	unsigned int err_len;
451
-	int poll_err;
452
-	
453
-	poll_err=0;
454
-	to=cfg_get(tcp, tcp_cfg, connect_timeout_s);
455
-	ticks=get_ticks();
456
-again:
457
-	n=connect(fd, servaddr, addrlen);
458
-	if (n==-1){
459
-		if (errno==EINTR){
460
-			elapsed=(get_ticks()-ticks)*TIMER_TICK;
461
-			if (elapsed<to)		goto again;
462
-			else goto error_timeout;
463
-		}
464
-		if (errno!=EINPROGRESS && errno!=EALREADY){
465
-			goto error_errno;
466
-		}
467
-	}else goto end;
468
-	
469
-	/* poll/select loop */
470
-#if defined(HAVE_SELECT) && defined(BLOCKING_USE_SELECT)
471
-		FD_ZERO(&orig_set);
472
-		FD_SET(fd, &orig_set);
473
-#else
474
-		pf.fd=fd;
475
-		pf.events=POLLOUT;
476
-#endif
477
-	while(1){
478
-		elapsed=(get_ticks()-ticks)*TIMER_TICK;
479
-		if (elapsed>=to)
480
-			goto error_timeout;
481
-#if defined(HAVE_SELECT) && defined(BLOCKING_USE_SELECT)
482
-		sel_set=orig_set;
483
-		timeout.tv_sec=to-elapsed;
484
-		timeout.tv_usec=0;
485
-		n=select(fd+1, 0, &sel_set, 0, &timeout);
486
-#else
487
-		n=poll(&pf, 1, (to-elapsed)*1000);
488
-#endif
489
-		if (n<0){
490
-			if (errno==EINTR) continue;
491
-			LM_ERR("%s: poll/select failed: (%d) %s\n",
492
-					su2a((union sockaddr_union*)servaddr, addrlen),
493
-					errno, strerror(errno));
494
-			goto error;
495
-		}else if (n==0) /* timeout */ continue;
496
-#if defined(HAVE_SELECT) && defined(BLOCKING_USE_SELECT)
497
-		if (FD_ISSET(fd, &sel_set))
498
-#else
499
-		if (pf.revents&(POLLERR|POLLHUP|POLLNVAL)){ 
500
-			LM_ERR("%s: poll error: flags %x\n",
501
-					su2a((union sockaddr_union*)servaddr, addrlen),
502
-					pf.revents);
503
-			poll_err=1;
504
-		}
505
-#endif
506
-		{
507
-			err_len=sizeof(err);
508
-			getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &err_len);
509
-			if ((err==0) && (poll_err==0)) goto end;
510
-			if (err!=EINPROGRESS && err!=EALREADY){
511
-				LM_ERR("%s: SO_ERROR (%d) %s\n",
512
-						su2a((union sockaddr_union*)servaddr, addrlen),
513
-						err, strerror(err));
514
-				errno=err;
515
-				goto error_errno;
516
-			}
517
-		}
518
-	}
519
-error_errno:
520
-	switch(errno){
521
-		case ENETUNREACH:
522
-		case EHOSTUNREACH:
523
-#ifdef USE_DST_BLACKLIST
524
-			dst_blacklist_su(BLST_ERR_CONNECT, type,
525
-							 (union sockaddr_union*)servaddr, send_flags, 0);
526
-#endif /* USE_DST_BLACKLIST */
527
-			TCP_EV_CONNECT_UNREACHABLE(errno, 0, 0,
528
-							(union sockaddr_union*)servaddr, type);
529
-			break;
530
-		case ETIMEDOUT:
531
-#ifdef USE_DST_BLACKLIST
532
-			dst_blacklist_su(BLST_ERR_CONNECT, type,
533
-							 (union sockaddr_union*)servaddr, send_flags, 0);
534
-#endif /* USE_DST_BLACKLIST */
535
-			TCP_EV_CONNECT_TIMEOUT(errno, 0, 0,
536
-							(union sockaddr_union*)servaddr, type);
537
-			break;
538
-		case ECONNREFUSED:
539
-		case ECONNRESET:
540
-#ifdef USE_DST_BLACKLIST
541
-			dst_blacklist_su(BLST_ERR_CONNECT, type,
542
-							 (union sockaddr_union*)servaddr, send_flags, 0);
543
-#endif /* USE_DST_BLACKLIST */
544
-			TCP_EV_CONNECT_RST(errno, 0, 0,
545
-							(union sockaddr_union*)servaddr, type);
546
-			break;
547
-		case EAGAIN: /* not posix, but supported on linux and bsd */
548
-			TCP_EV_CONNECT_NO_MORE_PORTS(errno, 0, 0,
549
-							(union sockaddr_union*)servaddr, type);
550
-			break;
551
-		default:
552
-			TCP_EV_CONNECT_ERR(errno, 0, 0,
553
-								(union sockaddr_union*)servaddr, type);
554
-	}
555
-	LM_ERR("%s: (%d) %s\n",
556
-			su2a((union sockaddr_union*)servaddr, addrlen),
557
-			errno, strerror(errno));
558
-	goto error;
559
-error_timeout:
560
-	/* timeout */
561
-#ifdef USE_DST_BLACKLIST
562
-	dst_blacklist_su(BLST_ERR_CONNECT, type,
563
-						(union sockaddr_union*)servaddr, send_flags, 0);
564
-#endif /* USE_DST_BLACKLIST */
565
-	TCP_EV_CONNECT_TIMEOUT(0, 0, 0, (union sockaddr_union*)servaddr, type);
566
-	LM_ERR("%s: timeout %d s elapsed from %d s\n",
567
-				su2a((union sockaddr_union*)servaddr, addrlen),
568
-				elapsed, cfg_get(tcp, tcp_cfg, connect_timeout_s));
569
-error:
570
-	TCP_STATS_CONNECT_FAILED();
571
-	return -1;
572
-end:
573
-	return 0;
574
-}
575
-
576
-
577
-
578
-#ifdef TCP_ASYNC
579
-
580
-
581
-/* unsafe version */
582
-#define _wbufq_empty(con) ((con)->wbuf_q.first==0)
583
-/* unsafe version */
584
-#define _wbufq_non_empty(con) ((con)->wbuf_q.first!=0)
585
-
586
-
587
-/* unsafe version, call while holding the connection write lock */
588
-inline static int _wbufq_add(struct  tcp_connection* c, const char* data, 
589
-							unsigned int size)
590
-{
591
-	struct tcp_wbuffer_queue* q;
592
-	struct tcp_wbuffer* wb;
593
-	unsigned int last_free;
594
-	unsigned int wb_size;
595
-	unsigned int crt_size;
596
-	ticks_t t;
597
-	
598
-	q=&c->wbuf_q;
599
-	t=get_ticks_raw();
600
-	if (unlikely(	((q->queued+size)>cfg_get(tcp, tcp_cfg, tcpconn_wq_max)) ||
601
-					((*tcp_total_wq+size)>cfg_get(tcp, tcp_cfg, tcp_wq_max)) ||
602
-					(q->first &&
603
-					TICKS_LT(q->wr_timeout, t)) )){
604
-		LM_ERR("(%d bytes): write queue full or timeout "
605
-					" (%d, total %d, last write %d s ago)\n",
606
-					size, q->queued, *tcp_total_wq,
607
-					TICKS_TO_S(t-(q->wr_timeout-
608
-								cfg_get(tcp, tcp_cfg, send_timeout))));
609
-		if (q->first && TICKS_LT(q->wr_timeout, t)){
610
-			if (unlikely(c->state==S_CONN_CONNECT)){
611
-#ifdef USE_DST_BLACKLIST
612
-				(void)dst_blacklist_su( BLST_ERR_CONNECT, c->rcv.proto,
613
-										&c->rcv.src_su, &c->send_flags, 0);
614
-#endif /* USE_DST_BLACKLIST */
615
-				TCP_EV_CONNECT_TIMEOUT(0, TCP_LADDR(c), TCP_LPORT(c),
616
-											TCP_PSU(c), TCP_PROTO(c));
617
-				TCP_STATS_CONNECT_FAILED();
618
-			}else{
619
-#ifdef USE_DST_BLACKLIST
620
-				(void)dst_blacklist_su( BLST_ERR_SEND, c->rcv.proto,
621
-									&c->rcv.src_su, &c->send_flags, 0);
622
-#endif /* USE_DST_BLACKLIST */
623
-				TCP_EV_SEND_TIMEOUT(0, &c->rcv);
624
-				TCP_STATS_SEND_TIMEOUT();
625
-			}
626
-		}else{
627
-			/* if it's not a timeout => queue full */
628
-			TCP_EV_SENDQ_FULL(0, &c->rcv);
629
-			TCP_STATS_SENDQ_FULL();
630
-		}
631
-		goto error;
632
-	}
633
-	
634
-	if (unlikely(q->last==0)){
635
-		wb_size=MAX_unsigned(cfg_get(tcp, tcp_cfg, wq_blk_size), size);
636
-		wb=shm_malloc(sizeof(*wb)+wb_size-1);
637
-		if (unlikely(wb==0))
638
-			goto error;
639
-		wb->b_size=wb_size;
640
-		wb->next=0;
641
-		q->last=wb;
642
-		q->first=wb;
643
-		q->last_used=0;
644
-		q->offset=0;
645
-		q->wr_timeout=get_ticks_raw()+
646
-			((c->state==S_CONN_CONNECT)?
647
-					S_TO_TICKS(cfg_get(tcp, tcp_cfg, connect_timeout_s)):
648
-					cfg_get(tcp, tcp_cfg, send_timeout));
649
-	}else{
650
-		wb=q->last;
651
-	}
652
-	
653
-	while(size){
654
-		last_free=wb->b_size-q->last_used;
655
-		if (last_free==0){
656
-			wb_size=MAX_unsigned(cfg_get(tcp, tcp_cfg, wq_blk_size), size);
657
-			wb=shm_malloc(sizeof(*wb)+wb_size-1);
658
-			if (unlikely(wb==0))
659
-				goto error;
660
-			wb->b_size=wb_size;
661
-			wb->next=0;
662
-			q->last->next=wb;
663
-			q->last=wb;
664
-			q->last_used=0;
665
-			last_free=wb->b_size;
666
-		}
667
-		crt_size=MIN_unsigned(last_free, size);
668
-		memcpy(wb->buf+q->last_used, data, crt_size);
669
-		q->last_used+=crt_size;
670
-		size-=crt_size;
671
-		data+=crt_size;
672
-		q->queued+=crt_size;
673
-		atomic_add_int((int*)tcp_total_wq, crt_size);
674
-	}
675
-	return 0;
676
-error:
677
-	return -1;
678
-}
679
-
680
-
681
-
682
-/* unsafe version, call while holding the connection write lock
683
- * inserts data at the beginning, it ignores the max queue size checks and
684
- * the timeout (use sparingly)
685
- * Note: it should never be called on a write buffer after wbufq_run() */
686
-inline static int _wbufq_insert(struct  tcp_connection* c, const char* data, 
687
-							unsigned int size)
688
-{
689
-	struct tcp_wbuffer_queue* q;
690
-	struct tcp_wbuffer* wb;
691
-	
692
-	q=&c->wbuf_q;
693
-	if (likely(q->first==0)) /* if empty, use wbufq_add */
694
-		return _wbufq_add(c, data, size);
695
-	
696
-	if (unlikely((*tcp_total_wq+size)>cfg_get(tcp, tcp_cfg, tcp_wq_max))){
697
-		LM_ERR("(%d bytes): write queue full"
698
-					" (%d, total %d, last write %d s ago)\n",
699
-					size, q->queued, *tcp_total_wq,
700
-					TICKS_TO_S(get_ticks_raw()-q->wr_timeout-
701
-									cfg_get(tcp, tcp_cfg, send_timeout)));
702
-		goto error;
703
-	}
704
-	if (unlikely(q->offset)){
705
-		LM_CRIT("non-null offset %d (bad call, should"
706
-				"never be called after the wbufq_run())\n", q->offset);
707
-		goto error;
708
-	}
709
-	if ((q->first==q->last) && ((q->last->b_size-q->last_used)>=size)){
710
-		/* one block with enough space in it for size bytes */
711
-		memmove(q->first->buf+size, q->first->buf, q->last_used);
712
-		memcpy(q->first->buf, data, size);
713
-		q->last_used+=size;
714
-	}else{
715
-		/* create a size bytes block directly */
716
-		wb=shm_malloc(sizeof(*wb)+size-1);
717
-		if (unlikely(wb==0))
718
-			goto error;
719
-		wb->b_size=size;
720
-		/* insert it */
721
-		wb->next=q->first;
722
-		q->first=wb;
723
-		memcpy(wb->buf, data, size);
724
-	}
725
-	
726
-	q->queued+=size;
727
-	atomic_add_int((int*)tcp_total_wq, size);
728
-	return 0;
729
-error:
730
-	return -1;
731
-}
732
-
733
-
734
-
735
-/* unsafe version, call while holding the connection write lock */
736
-inline static void _wbufq_destroy( struct  tcp_wbuffer_queue* q)
737
-{
738
-	struct tcp_wbuffer* wb;
739
-	struct tcp_wbuffer* next_wb;
740
-	int unqueued;
741
-	
742
-	unqueued=0;
743
-	if (likely(q->first)){
744
-		wb=q->first;
745
-		do{
746
-			next_wb=wb->next;
747
-			unqueued+=(wb==q->last)?q->last_used:wb->b_size;
748
-			if (wb==q->first)
749
-				unqueued-=q->offset;
750
-			shm_free(wb);
751
-			wb=next_wb;
752
-		}while(wb);
753
-	}
754
-	memset(q, 0, sizeof(*q));
755
-	atomic_add_int((int*)tcp_total_wq, -unqueued);
756
-}
757
-
758
-
759
-
760
-/* tries to empty the queue  (safe version, c->write_lock must not be hold)
761
- * returns -1 on error, bytes written on success (>=0) 
762
- * if the whole queue is emptied => sets *empty*/
763
-inline static int wbufq_run(int fd, struct tcp_connection* c, int* empty)
764
-{
765
-	struct tcp_wbuffer_queue* q;
766
-	struct tcp_wbuffer* wb;
767
-	int n;
768
-	int ret;
769
-	int block_size;
770
-	char* buf;
771
-	
772
-	*empty=0;
773
-	ret=0;
774
-	lock_get(&c->write_lock);
775
-	q=&c->wbuf_q;
776
-	while(q->first){
777
-		block_size=((q->first==q->last)?q->last_used:q->first->b_size)-
778
-						q->offset;
779
-		buf=q->first->buf+q->offset;
780
-		n=_tcpconn_write_nb(fd, c, buf, block_size);
781
-		if (likely(n>0)){
782
-			ret+=n;
783
-			if (likely(n==block_size)){
784
-				wb=q->first;
785
-				q->first=q->first->next; 
786
-				shm_free(wb);
787
-				q->offset=0;
788
-				q->queued-=block_size;
789
-				atomic_add_int((int*)tcp_total_wq, -block_size);
790
-			}else{
791
-				q->offset+=n;
792
-				q->queued-=n;
793
-				atomic_add_int((int*)tcp_total_wq, -n);
794
-				break;
795
-			}
796
-		}else{
797
-			if (n<0){
798
-				/* EINTR is handled inside _tcpconn_write_nb */
799
-				if (!(errno==EAGAIN || errno==EWOULDBLOCK)){
800
-					if (unlikely(c->state==S_CONN_CONNECT)){
801
-						switch(errno){
802
-							case ENETUNREACH:
803
-							case EHOSTUNREACH: /* not posix for send() */
804
-#ifdef USE_DST_BLACKLIST
805
-								dst_blacklist_su(BLST_ERR_CONNECT,
806
-													c->rcv.proto,
807
-													&c->rcv.src_su,
808
-													&c->send_flags, 0);
809
-#endif /* USE_DST_BLACKLIST */
810
-								TCP_EV_CONNECT_UNREACHABLE(errno, TCP_LADDR(c),
811
-													TCP_LPORT(c), TCP_PSU(c),
812
-													TCP_PROTO(c));
813
-								break;
814
-							case ECONNREFUSED:
815
-							case ECONNRESET:
816
-#ifdef USE_DST_BLACKLIST
817
-								dst_blacklist_su(BLST_ERR_CONNECT,
818
-													c->rcv.proto,
819
-													&c->rcv.src_su,
820
-													&c->send_flags, 0);
821
-#endif /* USE_DST_BLACKLIST */
822
-								TCP_EV_CONNECT_RST(0, TCP_LADDR(c),
823
-													TCP_LPORT(c), TCP_PSU(c),
824
-													TCP_PROTO(c));
825
-								break;
826
-							default:
827
-								TCP_EV_CONNECT_ERR(errno, TCP_LADDR(c),
828
-													TCP_LPORT(c), TCP_PSU(c),
829
-													TCP_PROTO(c));
830
-						}
831
-						TCP_STATS_CONNECT_FAILED();
832
-					}else{
833
-						switch(errno){
834
-							case ECONNREFUSED:
835
-							case ECONNRESET:
836
-								TCP_STATS_CON_RESET();
837
-								/* no break */
838
-							case ENETUNREACH:
839
-							case EHOSTUNREACH: /* not posix for send() */
840
-#ifdef USE_DST_BLACKLIST
841
-								dst_blacklist_su(BLST_ERR_SEND,
842
-													c->rcv.proto,
843
-													&c->rcv.src_su,
844
-													&c->send_flags, 0);
845
-#endif /* USE_DST_BLACKLIST */
846
-								break;
847
-						}
848
-					}
849
-					ret=-1;
850
-					LM_ERR("%s [%d]\n", strerror(errno), errno);
851
-				}
852
-			}
853
-			break;
854
-		}
855
-	}
856
-	if (likely(q->first==0)){
857
-		q->last=0;
858
-		q->last_used=0;
859
-		q->offset=0;
860
-		*empty=1;
861
-	}
862
-	lock_release(&c->write_lock);
863
-	if (likely(ret>0)){
864
-		q->wr_timeout=get_ticks_raw()+cfg_get(tcp, tcp_cfg, send_timeout);
865
-		if (unlikely(c->state==S_CONN_CONNECT || c->state==S_CONN_ACCEPT)){
866
-			TCP_STATS_ESTABLISHED(c->state);
867
-			c->state=S_CONN_OK;
868
-		}
869
-	}
870
-	return ret;
871
-}
872
-
873
-#endif /* TCP_ASYNC */
874
-
875
-
876
-
877
-#if 0
878
-/* blocking write even on non-blocking sockets 
879
- * if TCP_TIMEOUT will return with error */
880
-static int tcp_blocking_write(struct tcp_connection* c, int fd, char* buf,
881
-								unsigned int len)
882
-{
883
-	int n;
884
-	fd_set sel_set;
885
-	struct timeval timeout;
886
-	int ticks;
887
-	int initial_len;
888
-	
889
-	initial_len=len;
890
-again:
891
-	
892
-	n=send(fd, buf, len,
893
-#ifdef HAVE_MSG_NOSIGNAL
894
-			MSG_NOSIGNAL
895
-#else
896
-			0
897
-#endif
898
-		);
899
-	if (n<0){
900
-		if (errno==EINTR)	goto again;
901
-		else if (errno!=EAGAIN && errno!=EWOULDBLOCK){
902
-			LM_ERR("failed to send: (%d) %s\n", errno, strerror(errno));
903
-			TCP_EV_SEND_TIMEOUT(errno, &c->rcv);
904
-			TCP_STATS_SEND_TIMEOUT();
905