Browse code

- tcp switched to non-blocking sockets - tcp timeouts on send/connect introduced (see NEWS for cfg.) - fifo error msg. fix

Andrei Pelinescu-Onciul authored on 03/12/2003 12:15:04
Showing 8 changed files
... ...
@@ -45,7 +45,7 @@ export makefile_defs
45 45
 VERSION = 0
46 46
 PATCHLEVEL = 8
47 47
 SUBLEVEL =   12
48
-EXTRAVERSION = -nathelper
48
+EXTRAVERSION = -tcp_nonb
49 49
 
50 50
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
51 51
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")
... ...
@@ -7,6 +7,13 @@ $Id$
7 7
 * Changes/fixes introduced in 0.8.12-r1
8 8
 ***********************************************
9 9
 
10
+ - new config variables:$
11
+   tcp_connect_timeout= seconds$
12
+       time before an ongoing connect will be aborted$
13
+   tcp_send_timeout= seconds$
14
+       time after a tcp connection will be closed if it is not available.$
15
+       for writing in this interval (and ser wants to sen something on it)
16
+
10 17
  - full nathelper support (backported from HEAD)
11 18
  - openbsd 3.4 support
12 19
  - group fixed (ser crashed when started with a group)
... ...
@@ -41,8 +41,7 @@
41 41
  *  2003-10-02  added {,set_}advertised_{address,port} (andrei)
42 42
  *  2003-10-07  added hex and octal numbers support (andrei)
43 43
  *  2003-10-10  replaced len_gt w/ msg:len (andrei)
44
- *  2003-10-13  added fifo_dir (andrei)
45
- *  2003-10-28  added tcp_accept_aliases (andrei)
44
+ *  2003-11-29  added {tcp_send, tcp_connect, tls_*}_timeout (andrei)
46 45
  */
47 46
 
48 47
 
... ...
@@ -94,7 +93,6 @@ ROUTE_FAILURE failure_route
94 93
 ROUTE_ONREPLY onreply_route
95 94
 EXEC	exec
96 95
 FORCE_RPORT		"force_rport"|"add_rport"
97
-FORCE_TCP_ALIAS		"force_tcp_alias"|"add_tcp_alias"
98 96
 SETFLAG		setflag
99 97
 RESETFLAG	resetflag
100 98
 ISFLAGSET	isflagset
... ...
@@ -166,8 +164,6 @@ SYN_BRANCH syn_branch
166 164
 MEMLOG		"memlog"|"mem_log"
167 165
 SIP_WARNING sip_warning
168 166
 FIFO fifo
169
-FIFO_DIR  fifo_dir
170
-FIFO_DB_URL fifo_db_url
171 167
 FIFO_MODE fifo_mode
172 168
 SERVER_SIGNATURE server_signature
173 169
 REPLY_TO_VIA reply_to_via
... ...
@@ -178,7 +174,8 @@ WDIR		"workdir"|"wdir"
178 174
 MHOMED		mhomed
179 175
 DISABLE_TCP		"disable_tcp"
180 176
 TCP_CHILDREN	"tcp_children"
181
-TCP_ACCEPT_ALIASES	"tcp_accept_aliases"
177
+TCP_SEND_TIMEOUT	"tcp_send_timeout"
178
+TCP_CONNECT_TIMEOUT	"tcp_connect_timeout"
182 179
 DISABLE_TLS		"disable_tls"
183 180
 TLSLOG			"tlslog"|"tls_log"
184 181
 TLS_PORT_NO		"tls_port_no"
... ...
@@ -188,6 +185,8 @@ TLS_REQUIRE_CERTIFICATE "tls_require_certificate"
188 185
 TLS_CERTIFICATE	"tls_certificate"
189 186
 TLS_PRIVATE_KEY "tls_private_key"
190 187
 TLS_CA_LIST		"tls_ca_list"
188
+TLS_HANDSHAKE_TIMEOUT	"tls_handshake_timeout"
189
+TLS_SEND_TIMEOUT	"tls_send_timeout"
191 190
 ADVERTISED_ADDRESS	"advertised_address"
192 191
 ADVERTISED_PORT		"advertised_port"
193 192
 
... ...
@@ -228,8 +227,6 @@ RBRACE		\}
228 227
 LBRACK		\[
229 228
 RBRACK		\]
230 229
 COMMA		","
231
-COLON		":"
232
-STAR		\*
233 230
 DOT			\.
234 231
 CR			\n
235 232
 
... ...
@@ -278,8 +275,6 @@ EAT_ABLE	[\ \t\b\r]
278 275
 <INITIAL>{APPEND_BRANCH}	{ count(); yylval.strval=yytext; 
279 276
 								return APPEND_BRANCH; }
280 277
 <INITIAL>{FORCE_RPORT}	{ count(); yylval.strval=yytext; return FORCE_RPORT; }
281
-<INITIAL>{FORCE_TCP_ALIAS}	{ count(); yylval.strval=yytext;
282
-								return FORCE_TCP_ALIAS; }
283 278
 	
284 279
 <INITIAL>{IF}	{ count(); yylval.strval=yytext; return IF; }
285 280
 <INITIAL>{ELSE}	{ count(); yylval.strval=yytext; return ELSE; }
... ...
@@ -326,8 +321,10 @@ EAT_ABLE	[\ \t\b\r]
326 321
 <INITIAL>{MHOMED}	{ count(); yylval.strval=yytext; return MHOMED; }
327 322
 <INITIAL>{DISABLE_TCP}	{ count(); yylval.strval=yytext; return DISABLE_TCP; }
328 323
 <INITIAL>{TCP_CHILDREN}	{ count(); yylval.strval=yytext; return TCP_CHILDREN; }
329
-<INITIAL>{TCP_ACCEPT_ALIASES}	{ count(); yylval.strval=yytext;
330
-									return TCP_ACCEPT_ALIASES; }
324
+<INITIAL>{TCP_SEND_TIMEOUT}		{ count(); yylval.strval=yytext;
325
+									return TCP_SEND_TIMEOUT; }
326
+<INITIAL>{TCP_CONNECT_TIMEOUT}		{ count(); yylval.strval=yytext;
327
+									return TCP_CONNECT_TIMEOUT; }
331 328
 <INITIAL>{DISABLE_TLS}	{ count(); yylval.strval=yytext; return DISABLE_TLS; }
332 329
 <INITIAL>{TLSLOG}		{ count(); yylval.strval=yytext; return TLS_PORT_NO; }
333 330
 <INITIAL>{TLS_PORT_NO}	{ count(); yylval.strval=yytext; return TLS_PORT_NO; }
... ...
@@ -341,9 +338,11 @@ EAT_ABLE	[\ \t\b\r]
341 338
 										return TLS_PRIVATE_KEY; }
342 339
 <INITIAL>{TLS_CA_LIST}	{ count(); yylval.strval=yytext; 
343 340
 										return TLS_CA_LIST; }
341
+<INITIAL>{TLS_HANDSHAKE_TIMEOUT}	{ count(); yylval.strval=yytext;
342
+										return TLS_HANDSHAKE_TIMEOUT; }
343
+<INITIAL>{TLS_SEND_TIMEOUT}	{ count(); yylval.strval=yytext;
344
+										return TLS_SEND_TIMEOUT; }
344 345
 <INITIAL>{FIFO}	{ count(); yylval.strval=yytext; return FIFO; }
345
-<INITIAL>{FIFO_DIR}	{ count(); yylval.strval=yytext; return FIFO_DIR; }
346
-<INITIAL>{FIFO_DB_URL}	{ count(); yylval.strval=yytext; return FIFO_DB_URL; }
347 346
 <INITIAL>{FIFO_MODE}	{ count(); yylval.strval=yytext; return FIFO_MODE; }
348 347
 <INITIAL>{SERVER_SIGNATURE}	{ count(); yylval.strval=yytext; return SERVER_SIGNATURE; }
349 348
 <INITIAL>{REPLY_TO_VIA}	{ count(); yylval.strval=yytext; return REPLY_TO_VIA; }
... ...
@@ -376,9 +375,9 @@ EAT_ABLE	[\ \t\b\r]
376 375
 							return NUMBER; }
377 376
 <INITIAL>{YES}			{ count(); yylval.intval=1; return NUMBER; }
378 377
 <INITIAL>{NO}			{ count(); yylval.intval=0; return NUMBER; }
379
-<INITIAL>{TCP}			{ count(); return TCP; }
380
-<INITIAL>{UDP}			{ count(); return UDP; }
381
-<INITIAL>{TLS}			{ count(); return TLS; }
378
+<INITIAL>{TCP}			{ count(); yylval.intval=PROTO_TCP; return NUMBER; }
379
+<INITIAL>{UDP}			{ count(); yylval.intval=PROTO_UDP; return NUMBER; }
380
+<INITIAL>{TLS}			{ count(); yylval.intval=PROTO_TLS; return NUMBER; }
382 381
 <INITIAL>{INET}			{ count(); yylval.intval=AF_INET; return NUMBER; }
383 382
 <INITIAL>{INET6}		{ count();
384 383
 						#ifdef USE_IPV6
... ...
@@ -394,8 +393,6 @@ EAT_ABLE	[\ \t\b\r]
394 393
 
395 394
 <INITIAL>{COMMA}		{ count(); return COMMA; }
396 395
 <INITIAL>{SEMICOLON}	{ count(); return SEMICOLON; }
397
-<INITIAL>{COLON}	{ count(); return COLON; }
398
-<INITIAL>{STAR}	{ count(); return STAR; }
399 396
 <INITIAL>{RPAREN}	{ count(); return RPAREN; }
400 397
 <INITIAL>{LPAREN}	{ count(); return LPAREN; }
401 398
 <INITIAL>{LBRACE}	{ count(); return LBRACE; }
... ...
@@ -46,6 +46,7 @@
46 46
  * 2003-10-10  added <,>,<=,>=, != operators support
47 47
  *             added msg:len (andrei)
48 48
  * 2003-10-11  if(){} doesn't require a ';' after it anymore (andrei)
49
+ * 2003-11-20  added {tcp_connect, tcp_send, tls_*}_timeout (andrei)
49 50
  */
50 51
 
51 52
 
... ...
@@ -191,10 +192,14 @@ void warn(char* s);
191 192
 %token MHOMED
192 193
 %token DISABLE_TCP
193 194
 %token TCP_CHILDREN
195
+%token TCP_CONNECT_TIMEOUT
196
+%token TCP_SEND_TIMEOUT
194 197
 %token DISABLE_TLS
195 198
 %token TLSLOG
196 199
 %token TLS_PORT_NO
197 200
 %token TLS_METHOD
201
+%token TLS_HANDSHAKE_TIMEOUT
202
+%token TLS_SEND_TIMEOUT
198 203
 %token SSLv23
199 204
 %token SSLv2
200 205
 %token SSLv3
... ...
@@ -398,6 +403,22 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
398 403
 									#endif
399 404
 									}
400 405
 		| TCP_CHILDREN EQUAL error { yyerror("number expected"); }
406
+		| TCP_CONNECT_TIMEOUT EQUAL NUMBER {
407
+									#ifdef USE_TCP
408
+										tcp_connect_timeout=$3;
409
+									#else
410
+										warn("tcp support not compiled in");
411
+									#endif
412
+									}
413
+		| TCP_CONNECT_TIMEOUT EQUAL error { yyerror("number expected"); }
414
+		| TCP_SEND_TIMEOUT EQUAL NUMBER {
415
+									#ifdef USE_TCP
416
+										tcp_send_timeout=$3;
417
+									#else
418
+										warn("tcp support not compiled in");
419
+									#endif
420
+									}
421
+		| TCP_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
401 422
 		| DISABLE_TLS EQUAL NUMBER {
402 423
 									#ifdef USE_TLS
403 424
 										tls_disable=$3;
... ...
@@ -500,6 +521,22 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
500 521
 									#endif
501 522
 									}
502 523
 		| TLS_CA_LIST EQUAL error { yyerror("string value expected"); }
524
+		| TLS_HANDSHAKE_TIMEOUT EQUAL NUMBER {
525
+									#ifdef USE_TLS
526
+										tls_handshake_timeout=$3;
527
+									#else
528
+										warn("tls support not compiled in");
529
+									#endif
530
+									}
531
+		| TLS_HANDSHAKE_TIMEOUT EQUAL error { yyerror("number expected"); }
532
+		| TLS_SEND_TIMEOUT EQUAL NUMBER {
533
+									#ifdef USE_TLS
534
+										tls_send_timeout=$3;
535
+									#else
536
+										warn("tls support not compiled in");
537
+									#endif
538
+									}
539
+		| TLS_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
503 540
 		| SERVER_SIGNATURE EQUAL NUMBER { server_signature=$3; }
504 541
 		| SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
505 542
 		| REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; }
... ...
@@ -529,6 +529,7 @@ int open_fifo_server()
529 529
 {
530 530
 	char *t;
531 531
 	struct stat filestat;
532
+	int n;
532 533
 #ifdef USE_TCP
533 534
 	int sockfd[2];
534 535
 #endif
... ...
@@ -543,17 +544,19 @@ int open_fifo_server()
543 544
 		return 1;
544 545
 	}
545 546
 	DBG("DBG: open_uac_fifo: opening fifo...\n");
546
-	if (stat(fifo, &filestat)==0){
547
+	n=stat(fifo, &filestat);
548
+	if (n==0){
547 549
 		/* FIFO exist, delete it (safer) */
548 550
 		if (unlink(fifo)<0){
549 551
 			LOG(L_ERR, "ERROR: open_fifo_server: cannot delete old fifo (%s):"
550 552
 					" %s\n", fifo, strerror(errno));
551 553
 			return -1;
552 554
 		}
553
-	}
554
-	 /* create FIFO ... */
555
+	}else if (n<0 && errno!=ENOENT){
555 556
 		LOG(L_DBG, "DEBUG: open_fifo_server: FIFO stat failed: %s\n",
556 557
 			strerror(errno));
558
+	}
559
+	/* create FIFO ... */
557 560
 		if ((mkfifo(fifo, fifo_mode)<0)) {
558 561
 			LOG(L_ERR, "ERROR: open_fifo_server; can't create FIFO: "
559 562
 					"%s (mode=%d)\n",
... ...
@@ -46,10 +46,19 @@
46 46
 extern char * cfg_file;
47 47
 extern int config_check;
48 48
 extern char *stat_file;
49
+extern struct socket_info sock_info[]; /* all addresses we listen/send from*/
50
+#ifdef USE_TCP
51
+extern struct socket_info tcp_info[]; /* all tcp sockets we listen on*/
52
+#endif
53
+#ifdef USE_TLS
54
+extern struct socket_info tls_info[]; /* tcp-tls sockets */
55
+#endif
56
+extern int sock_no; /* number of addresses/open sockets*/
49 57
 extern unsigned short port_no;
50 58
 
51 59
 extern struct socket_info* bind_address; /* pointer to the crt. proc.
52 60
 											listening address */
61
+extern int bind_idx; /* same as above but index in the bound[] array */
53 62
 extern struct socket_info* sendipv4; /* ipv4 socket to use when msg.
54 63
 										comes from ipv6*/
55 64
 extern struct socket_info* sendipv6; /* same as above for ipv6 */
... ...
@@ -70,7 +79,8 @@ extern int children_no;
70 79
 #ifdef USE_TCP
71 80
 extern int tcp_children_no;
72 81
 extern int tcp_disable;
73
-extern int tcp_accept_aliases;
82
+extern int tcp_connect_timeout;
83
+extern int tcp_send_timeout;
74 84
 #endif
75 85
 #ifdef USE_TLS
76 86
 extern int tls_disable;
... ...
@@ -102,8 +112,6 @@ extern unsigned int shm_mem_size;
102 112
 /* FIFO server config */
103 113
 char extern *fifo; /* FIFO name */
104 114
 extern int fifo_mode;
105
-char extern *fifo_dir; /* dir. where  reply fifos are allowed */
106
-extern char *fifo_db_url;  /* db url used by db_fifo interface */
107 115
 
108 116
 /* moved to pt.h
109 117
 extern int *pids;
... ...
@@ -43,6 +43,10 @@
43 43
 #define TCP_BUF_SIZE 65535
44 44
 #define TCP_CON_TIMEOUT 600 /* in  seconds */
45 45
 #define TCP_CON_SEND_TIMEOUT 600 /* timeout after a send */
46
+#define DEFAULT_TCP_SEND_TIMEOUT 10 /* if a send can't write for more then 10s,
47
+									   timeout */
48
+#define DEFAULT_TCP_CONNECT_TIMEOUT 10 /* if a connect doesn't complete in this
49
+										  time, timeout */
46 50
 #define TCP_CHILD_TIMEOUT 5 /* after 5 seconds, the child "returns" 
47 51
 							 the connection to the tcp master process */
48 52
 #define TCP_MAIN_SELECT_TIMEOUT 5 /* how often "tcp main" checks for timeout*/
... ...
@@ -48,6 +48,7 @@
48 48
  *              to/from readers/writers (andrei)
49 49
  *  2003-11-17  handle_new_connect & tcp_connect will close the 
50 50
  *              new socket if tcpconn_new return 0 (e.g. out of mem) (andrei)
51
+ *  2003-11-28  tcp_blocking_write & tcp_blocking_connect added (andrei)
51 52
  */
52 53
 
53 54
 
... ...
@@ -71,6 +72,7 @@
71 72
 #include <netdb.h>
72 73
 
73 74
 #include <unistd.h>
75
+#include <fcntl.h>
74 76
 
75 77
 #include <errno.h>
76 78
 #include <string.h>
... ...
@@ -110,6 +112,8 @@ struct tcp_child{
110 112
 };
111 113
 
112 114
 
115
+int tcp_connect_timeout=DEFAULT_TCP_CONNECT_TIMEOUT;
116
+int tcp_send_timeout=DEFAULT_TCP_SEND_TIMEOUT;
113 117
 
114 118
 /* connection hash table (after ip&port) */
115 119
 struct tcp_connection** tcpconn_addr_hash=0;
... ...
@@ -126,6 +130,179 @@ int unix_tcp_sock;
126 130
 int tcp_proto_no=-1; /* tcp protocol number as returned by getprotobyname */
127 131
 
128 132
 
133
+
134
+/* set all socket/fd options:  disable nagle, tos lowdelay, non-blocking
135
+ * return -1 on error */
136
+static int init_sock_opt(int s)
137
+{
138
+	int flags;
139
+	int optval;
140
+	
141
+#ifdef DISABLE_NAGLE
142
+	flags=1;
143
+	if ( (tcp_proto_no!=-1) && (setsockopt(s, tcp_proto_no , TCP_NODELAY,
144
+					&flags, sizeof(flags))<0) ){
145
+		LOG(L_WARN, "WARNING: init_sock_opt: could not disable Nagle: %s\n",
146
+				strerror(errno));
147
+	}
148
+#endif
149
+	/* tos*/
150
+	optval=IPTOS_LOWDELAY;
151
+	if (setsockopt(s, IPPROTO_IP, IP_TOS, (void*)&optval,sizeof(optval)) ==-1){
152
+		LOG(L_WARN, "WARNING: init_sock_opt: setsockopt tos: %s\n",
153
+				strerror(errno));
154
+		/* continue since this is not critical */
155
+	}
156
+	/* non-blocking */
157
+	flags=fcntl(s, F_GETFL);
158
+	if (flags==-1){
159
+		LOG(L_ERR, "ERROR: init_sock_opt: fnctl failed: (%d) %s\n",
160
+				errno, strerror(errno));
161
+		goto error;
162
+	}
163
+	if (fcntl(s, F_SETFL, flags|O_NONBLOCK)==-1){
164
+		LOG(L_ERR, "ERROR: init_sock_opt: fcntl: set non-blocking failed:"
165
+				" (%d) %s\n", errno, strerror(errno));
166
+		goto error;
167
+	}
168
+	return 0;
169
+error:
170
+	return -1;
171
+}
172
+
173
+
174
+
175
+static int tcp_blocking_connect(int fd, const struct sockaddr *servaddr,
176
+								socklen_t addrlen)
177
+{
178
+	int n;
179
+	fd_set sel_set;
180
+	struct timeval timeout;
181
+	int ticks;
182
+	int err;
183
+	int err_len;
184
+	
185
+again:
186
+	n=connect(fd, servaddr, addrlen);
187
+	if (n==-1){
188
+		if (errno==EINTR) goto again;
189
+		if (errno!=EINPROGRESS && errno!=EALREADY){
190
+			LOG(L_ERR, "ERROR: tcp_blocking_connect: (%d) %s\n",
191
+					errno, strerror(errno));
192
+			goto error;
193
+		}
194
+	}else goto end;
195
+	
196
+	while(1){
197
+		FD_ZERO(&sel_set);
198
+		FD_SET(fd, &sel_set);
199
+		timeout.tv_sec=tcp_connect_timeout;
200
+		timeout.tv_usec=0;
201
+		ticks=get_ticks();
202
+		n=select(fd+1, 0, &sel_set, 0, &timeout);
203
+		if (n<0){
204
+			if (errno==EINTR) continue;
205
+			LOG(L_ERR, "ERROR: tcp_blocking_connect: select failed: (%d) %s\n",
206
+					errno, strerror(errno));
207
+			goto error;
208
+		}else if (n==0){
209
+			/* timeout */
210
+			if (get_ticks()-ticks>=tcp_connect_timeout){
211
+				LOG(L_ERR, "ERROR: tcp_blocking_connect: timeout (%d)\n",
212
+						tcp_connect_timeout);
213
+				goto error;
214
+			}
215
+			continue;
216
+		}
217
+		if (FD_ISSET(fd, &sel_set)){
218
+			err_len=sizeof(err);
219
+			getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &err_len);
220
+			if (err==0) goto end;
221
+			if (err!=EINPROGRESS && err!=EALREADY){
222
+				LOG(L_ERR, "ERROR: tcp_blocking_connect: SO_ERROR (%d) %s\n",
223
+						err, strerror(err));
224
+				goto error;
225
+			}
226
+		}
227
+	}
228
+error:
229
+	return -1;
230
+end:
231
+	return 0;
232
+}
233
+
234
+
235
+
236
+/* blocking write even on non-blocking sockets 
237
+ * if TCP_TIMEOUT will return with error */
238
+static int tcp_blocking_write(struct tcp_connection* c, int fd, char* buf,
239
+								unsigned int len)
240
+{
241
+	int n;
242
+	fd_set sel_set;
243
+	struct timeval timeout;
244
+	int ticks;
245
+	int initial_len;
246
+	
247
+	initial_len=len;
248
+again:
249
+	
250
+	n=send(fd, buf, len,
251
+#ifdef HAVE_MSG_NOSIGNAL
252
+			MSG_NOSIGNAL
253
+#else
254
+			0
255
+#endif
256
+		);
257
+	if (n<0){
258
+		if (errno==EINTR)	goto again;
259
+		else if (errno!=EAGAIN && errno!=EWOULDBLOCK){
260
+			LOG(L_ERR, "tcp_blocking_write: failed to send: (%d) %s\n",
261
+					errno, strerror(errno));
262
+			goto error;
263
+		}
264
+	}else if (n<len){
265
+		/* partial write */
266
+		buf+=n;
267
+		len-=n;
268
+	}else{
269
+		/* success: full write */
270
+		goto end;
271
+	}
272
+	while(1){
273
+		FD_ZERO(&sel_set);
274
+		FD_SET(fd, &sel_set);
275
+		timeout.tv_sec=tcp_send_timeout;
276
+		timeout.tv_usec=0;
277
+		ticks=get_ticks();
278
+		n=select(fd+1, 0, &sel_set, 0, &timeout);
279
+		if (n<0){
280
+			if (errno==EINTR) continue; /* signal, ignore */
281
+			LOG(L_ERR, "ERROR: tcp_blocking_write: select failed: "
282
+					" (%d) %s\n", errno, strerror(errno));
283
+			goto error;
284
+		}else if (n==0){
285
+			/* timeout */
286
+			if (get_ticks()-ticks>=tcp_send_timeout){
287
+				LOG(L_ERR, "ERROR: tcp_blocking_write: send timeout (%d)\n",
288
+						tcp_send_timeout);
289
+				goto error;
290
+			}
291
+			continue;
292
+		}
293
+		if (FD_ISSET(fd, &sel_set)){
294
+			/* we can write again */
295
+			goto again;
296
+		}
297
+	}
298
+error:
299
+		return -1;
300
+end:
301
+		return initial_len;
302
+}
303
+
304
+
305
+
129 306
 struct tcp_connection* tcpconn_new(int sock, union sockaddr_union* su,
130 307
 									struct socket_info* ba, int type, 
131 308
 									int state)
... ...
@@ -206,11 +383,7 @@ struct tcp_connection* tcpconn_connect(union sockaddr_union* server, int type)
206 383
 	struct socket_info* si;
207 384
 	union sockaddr_union my_name;
208 385
 	socklen_t my_name_len;
209
-	int optval;
210 386
 	struct tcp_connection* con;
211
-#ifdef DISABLE_NAGLE
212
-	int flag;
213
-#endif
214 387
 
215 388
 	s=socket(AF2PF(server->s.sa_family), SOCK_STREAM, 0);
216 389
 	if (s==-1){
... ...
@@ -218,25 +391,12 @@ struct tcp_connection* tcpconn_connect(union sockaddr_union* server, int type)
218 391
 				errno, strerror(errno));
219 392
 		goto error;
220 393
 	}
221
-#ifdef DISABLE_NAGLE
222
-	flag=1;
223
-	if ( (tcp_proto_no!=-1) && (setsockopt(s, tcp_proto_no , TCP_NODELAY,
224
-					&flag, sizeof(flag))<0) ){
225
-		LOG(L_ERR, "ERROR: tcp_connect: could not disable Nagle: %s\n",
226
-				strerror(errno));
227
-	}
228
-#endif
229
-	/* tos*/
230
-	optval=IPTOS_LOWDELAY;
231
-	if (setsockopt(s, IPPROTO_IP, IP_TOS, (void*)&optval, sizeof(optval)) ==-1){
232
-		LOG(L_WARN, "WARNING: tcpconn_connect: setsockopt tos: %s\n",
233
-				strerror(errno));
234
-		/* continue since this is not critical */
394
+	if (init_sock_opt(s)<0){
395
+		LOG(L_ERR, "ERROR: tcpconn_connect: init_sock_opt failed\n");
396
+		goto error;
235 397
 	}
236
-
237
-	if (connect(s, &server->s, sockaddru_len(*server))<0){
238
-		LOG(L_ERR, "ERROR: tcpconn_connect: connect: (%d) %s\n",
239
-				errno, strerror(errno));
398
+	if (tcp_blocking_connect(s, &server->s, sockaddru_len(*server))<0){
399
+		LOG(L_ERR, "ERROR: tcpconn_connect: tcp_blocking_connect failed\n");
240 400
 		goto error;
241 401
 	}
242 402
 	my_name_len=sizeof(my_name);
... ...
@@ -513,21 +673,12 @@ send_it:
513 673
 		n=tls_blocking_write(c, fd, buf, len);
514 674
 	else
515 675
 #endif
516
-		n=send(fd, buf, len,
517
-#ifdef HAVE_MSG_NOSIGNAL
518
-			MSG_NOSIGNAL
519
-#else
520
-			0
521
-#endif
522
-			);
676
+		n=tcp_blocking_write(c, fd, buf, len);
523 677
 	lock_release(&c->write_lock);
524 678
 	DBG("tcp_send: after write: c= %p n=%d fd=%d\n",c, n, fd);
525 679
 	DBG("tcp_send: buf=\n%.*s\n", (int)len, buf);
526 680
 	if (n<0){
527
-		if (errno==EINTR) goto send_it; /* interrupted write, try again*/
528
-										/* keep the lock or lock/unlock again?*/
529
-		LOG(L_ERR, "ERROR: tcpsend: failed to send, n=%d: %s (%d)\n",
530
-				n, strerror(errno), errno);
681
+		LOG(L_ERR, "ERROR: tcp_send: failed to send\n");
531 682
 		/* error on the connection , mark it as bad and set 0 timeout */
532 683
 		c->state=S_CONN_BAD;
533 684
 		c->timeout=0;
... ...
@@ -742,6 +893,11 @@ static inline void handle_new_connect(struct socket_info* si,
742 893
 					" connection(%d): %s\n", errno, strerror(errno));
743 894
 			return;
744 895
 		}
896
+		if (init_sock_opt(new_sock)<0){
897
+			LOG(L_ERR, "ERROR: tcp_main_loop: init_sock_opt failed\n");
898
+			close(new_sock);
899
+			return;
900
+		}
745 901
 		
746 902
 		/* add socket to list */
747 903
 		tcpconn=tcpconn_new(new_sock, &su, si, si->proto, S_CONN_ACCEPT);