Browse code

- tcp send/connext timeout (read NEWS for the new cfg. parameters) - tcp switched to non-blocking fd (untested)

Andrei Pelinescu-Onciul authored on 29/11/2003 21:15:32
Showing 6 changed files
... ...
@@ -3,16 +3,12 @@ Release notes for SIP Express Router (ser)
3 3
 
4 4
 $Id$
5 5
 
6
-0.8.12 changes
6
+0.8.13 changes
7 7
 
8 8
 new modules:
9 9
  - answer server options requests [options]
10
-texops:
11
- - subst('s/re/repl/flags') support
12 10
 core:
13
- - added switch to check the config file (-c)
14 11
  - changes: 
15
-       removed len_gt() and replaced with if (msg:len op number|max_len)
16 12
        protocol and port can be specified in the alias and listen lines, e.g.:
17 13
         alias= tcp:foo.bar:* udp:test.bar:5080 foo.com
18 14
         listen= eth0   tcp:eth0:5065 udp:127.0.0.1 [3ffe::1]
... ...
@@ -20,20 +16,11 @@ core:
20 20
                               ==, !=, ~= for strings
21 21
                               ==, !=, >, <, >=, <= for integers
22 22
  - new config variables:
23
-     advertised_address= ip | string
24
-       address advertised in via and in the DST_* lumps (e.g RR)
25
-       This is the default value, if empty (default) the socket
26
-       address will be used.
27
-       WARNING: - don't set it unless you know what you are doing
28
-                 (e.g. nat traversal)
29
-               - you can set anything here, no check is made
30
-                (e.g. foo.bar will be accepted even if 
31
-                 foo.bar doesn't exist)
32
-    advertised_port= no
33
-       port advertised in via and in the DST_*lumps (e.g. RR)
34
-       This is the default value, if empty (default) the socket
35
-       port will be used.
36
-       Same warnings as above.
23
+   tcp_connect_timeout= seconds
24
+       time before an ongoing connect will be aborted
25
+   tcp_send_timeout= seconds
26
+       time after a tcp connection will be closed if it is not available 
27
+       for writing in this interval (and ser wants to sen something on it)
37 28
    tcp_accept_aliases= yes|no
38 29
        if a message received over a tcp connection has "alias" in its via
39 30
        a new tcp alias port will be created for the connection the message
... ...
@@ -43,13 +30,6 @@ core:
43 43
         lookups and the need for them is questionable)
44 44
        See force_tcp_alias for more details.
45 45
  - new script commands:
46
-    set_advertised_address(ip|string)
47
-       same as advertised_address but it affects only the current message:
48
-       Message host/lump address= the set_advertised one if
49
-       present, else advertised_address else socket address.
50
-    set_advertised_port(no)
51
-       same as advertised_port but it affects only the current
52
-       message; see set_advertised_address & s/address/port/g
53 46
    force_tcp_alias()
54 47
    force_tcp_alias(port)
55 48
        adds a tcp port alias for the current connection (if tcp).
... ...
@@ -69,6 +49,80 @@ core:
69 69
 
70 70
 
71 71
 
72
+***********************************************
73
+* Changes/fixes introduced in 0.8.12
74
+***********************************************
75
++--------------------------------------------------------+
76
+| WARNING: if you want to use a 0.8.11 config script     |
77
+| with 0.8.12, replace if ( len_gt(number) ) with:       |
78
+|                      if ( msg:len > bumber )           |
79
++--------------------------------------------------------+
80
+
81
+New Features
82
+============
83
+
84
+texops:
85
+ - subst('s/re/repl/flags') support
86
+core:
87
+ - added switch to check the config file (-c)
88
+ - changes: removed len_gt() and replaced with if (msg:len op number|max_len)
89
+ - multiple operator support: ==, != for special operations (e.g myself, ip)
90
+                              ==, !=, ~= for strings
91
+                              ==, !=, >, <, >=, <= for integers
92
+ - new config variables:
93
+     advertised_address= ip | string
94
+       address advertised in via and in the DST_* lumps (e.g RR)
95
+       This is the default value, if empty (default) the socket
96
+       address will be used.
97
+       WARNING: - don't set it unless you know what you are doing
98
+                 (e.g. nat traversal)
99
+               - you can set anything here, no check is made
100
+                (e.g. foo.bar will be accepted even if 
101
+                 foo.bar doesn't exist)
102
+    advertised_port= no
103
+       port advertised in via and in the DST_*lumps (e.g. RR)
104
+       This is the default value, if empty (default) the socket
105
+       port will be used.
106
+       Same warnings as above.
107
+ - new script commands:
108
+    set_advertised_address(ip|string)
109
+       same as advertised_address but it affects only the current message:
110
+       Message host/lump address= the set_advertised one if
111
+       present, else advertised_address else socket address.
112
+    set_advertised_port(no)
113
+       same as advertised_port but it affects only the current
114
+       message; see set_advertised_address & s/address/port/g
115
+
116
+usrloc:
117
+ - usernames are case insensitive
118
+ 
119
+registrar:
120
+ - lookup function succeeds when appending of a branch failed
121
+
122
+auth_db:
123
+ - support for rpid stored in database (thanks to Jakob Schlyter)
124
+
125
+Bug fixes
126
+=========
127
+- memory leak in digest credentials parser fixed
128
+- authenticathion ha1 didn't include domain if username was of the form
129
+  user@domain and calculate_ha1 was set to yes (modules/auth_db)
130
+- tm reply processing race condition (modules/tm), special thanks go to
131
+ Dong Liu
132
+- Many bugs in pa module fixed, works with registrar again.
133
+ 
134
+Security updates
135
+================
136
+ 
137
+- fifo processing code will write responses only to other
138
+ fifos and only if they are not hard-linked, also default
139
+ ser fifo persmissions were changed to 0600.
140
+                                                                                
141
+Performance improvements
142
+========================
143
+- tuned internal malloc implementation parameters to better reflect the
144
+actual workload (malloc is a little bit faster now)
145
+
72 146
 
73 147
 
74 148
 ***********************************************
... ...
@@ -92,7 +146,7 @@ New features
92 92
 	- ENUM support [enum]
93 93
 	- presence agent [pa]
94 94
 	- dynamic domain management -- allows to manipulate 
95
-  	  hosting of multiple domains in run-time [module]
95
+	  hosting of multiple domains in run-time [module]
96 96
 	- flat-text-file database support [dbtext]
97 97
 	- rich access control lists [permissions]
98 98
 - Feature Improvements
... ...
@@ -43,6 +43,7 @@
43 43
  *  2003-10-10  replaced len_gt w/ msg:len (andrei)
44 44
  *  2003-10-13  added fifo_dir (andrei)
45 45
  *  2003-10-28  added tcp_accept_aliases (andrei)
46
+ *  2003-11-29  added {tcp_send, tcp_connect, tls_*}_timeout (andrei)
46 47
  */
47 48
 
48 49
 
... ...
@@ -179,6 +180,8 @@ MHOMED		mhomed
179 179
 DISABLE_TCP		"disable_tcp"
180 180
 TCP_CHILDREN	"tcp_children"
181 181
 TCP_ACCEPT_ALIASES	"tcp_accept_aliases"
182
+TCP_SEND_TIMEOUT	"tcp_send_timeout"
183
+TCP_CONNECT_TIMEOUT	"tcp_connect_timeout"
182 184
 DISABLE_TLS		"disable_tls"
183 185
 TLSLOG			"tlslog"|"tls_log"
184 186
 TLS_PORT_NO		"tls_port_no"
... ...
@@ -188,6 +191,8 @@ TLS_REQUIRE_CERTIFICATE "tls_require_certificate"
188 188
 TLS_CERTIFICATE	"tls_certificate"
189 189
 TLS_PRIVATE_KEY "tls_private_key"
190 190
 TLS_CA_LIST		"tls_ca_list"
191
+TLS_HANDSHAKE_TIMEOUT	"tls_handshake_timeout"
192
+TLS_SEND_TIMEOUT	"tls_send_timeout"
191 193
 ADVERTISED_ADDRESS	"advertised_address"
192 194
 ADVERTISED_PORT		"advertised_port"
193 195
 
... ...
@@ -328,6 +333,10 @@ EAT_ABLE	[\ \t\b\r]
328 328
 <INITIAL>{TCP_CHILDREN}	{ count(); yylval.strval=yytext; return TCP_CHILDREN; }
329 329
 <INITIAL>{TCP_ACCEPT_ALIASES}	{ count(); yylval.strval=yytext;
330 330
 									return TCP_ACCEPT_ALIASES; }
331
+<INITIAL>{TCP_SEND_TIMEOUT}		{ count(); yylval.strval=yytext;
332
+									return TCP_SEND_TIMEOUT; }
333
+<INITIAL>{TCP_CONNECT_TIMEOUT}		{ count(); yylval.strval=yytext;
334
+									return TCP_CONNECT_TIMEOUT; }
331 335
 <INITIAL>{DISABLE_TLS}	{ count(); yylval.strval=yytext; return DISABLE_TLS; }
332 336
 <INITIAL>{TLSLOG}		{ count(); yylval.strval=yytext; return TLS_PORT_NO; }
333 337
 <INITIAL>{TLS_PORT_NO}	{ count(); yylval.strval=yytext; return TLS_PORT_NO; }
... ...
@@ -341,6 +350,10 @@ EAT_ABLE	[\ \t\b\r]
341 341
 										return TLS_PRIVATE_KEY; }
342 342
 <INITIAL>{TLS_CA_LIST}	{ count(); yylval.strval=yytext; 
343 343
 										return TLS_CA_LIST; }
344
+<INITIAL>{TLS_HANDSHAKE_TIMEOUT}	{ count(); yylval.strval=yytext;
345
+										return TLS_HANDSHAKE_TIMEOUT; }
346
+<INITIAL>{TLS_SEND_TIMEOUT}	{ count(); yylval.strval=yytext;
347
+										return TLS_SEND_TIMEOUT; }
344 348
 <INITIAL>{FIFO}	{ count(); yylval.strval=yytext; return FIFO; }
345 349
 <INITIAL>{FIFO_DIR}	{ count(); yylval.strval=yytext; return FIFO_DIR; }
346 350
 <INITIAL>{FIFO_DB_URL}	{ count(); yylval.strval=yytext; return FIFO_DB_URL; }
... ...
@@ -49,6 +49,7 @@
49 49
  * 2003-10-13  added FIFO_DIR & proto:host:port listen/alias support (andrei)
50 50
  * 2003-10-24  converted to the new socket_info lists (andrei)
51 51
  * 2003-10-28  added tcp_accept_aliases (andrei)
52
+ * 2003-11-20  added {tcp_connect, tcp_send, tls_*}_timeout (andrei)
52 53
  */
53 54
 
54 55
 
... ...
@@ -206,10 +207,14 @@ static struct id_list* mk_listen_id(char*, int, int);
206 206
 %token DISABLE_TCP
207 207
 %token TCP_ACCEPT_ALIASES
208 208
 %token TCP_CHILDREN
209
+%token TCP_CONNECT_TIMEOUT
210
+%token TCP_SEND_TIMEOUT
209 211
 %token DISABLE_TLS
210 212
 %token TLSLOG
211 213
 %token TLS_PORT_NO
212 214
 %token TLS_METHOD
215
+%token TLS_HANDSHAKE_TIMEOUT
216
+%token TLS_SEND_TIMEOUT
213 217
 %token SSLv23
214 218
 %token SSLv2
215 219
 %token SSLv3
... ...
@@ -428,6 +433,22 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
428 428
 									#endif
429 429
 									}
430 430
 		| TCP_CHILDREN EQUAL error { yyerror("number expected"); }
431
+		| TCP_CONNECT_TIMEOUT EQUAL NUMBER {
432
+									#ifdef USE_TCP
433
+										tcp_connect_timeout=$3;
434
+									#else
435
+										warn("tcp support not compiled in");
436
+									#endif
437
+									}
438
+		| TCP_CONNECT_TIMEOUT EQUAL error { yyerror("number expected"); }
439
+		| TCP_SEND_TIMEOUT EQUAL NUMBER {
440
+									#ifdef USE_TCP
441
+										tcp_send_timeout=$3;
442
+									#else
443
+										warn("tcp support not compiled in");
444
+									#endif
445
+									}
446
+		| TCP_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
431 447
 		| DISABLE_TLS EQUAL NUMBER {
432 448
 									#ifdef USE_TLS
433 449
 										tls_disable=$3;
... ...
@@ -530,6 +551,22 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
530 530
 									#endif
531 531
 									}
532 532
 		| TLS_CA_LIST EQUAL error { yyerror("string value expected"); }
533
+		| TLS_HANDSHAKE_TIMEOUT EQUAL NUMBER {
534
+									#ifdef USE_TLS
535
+										tls_handshake_timeout=$3;
536
+									#else
537
+										warn("tls support not compiled in");
538
+									#endif
539
+									}
540
+		| TLS_HANDSHAKE_TIMEOUT EQUAL error { yyerror("number expected"); }
541
+		| TLS_SEND_TIMEOUT EQUAL NUMBER {
542
+									#ifdef USE_TLS
543
+										tls_send_timeout=$3;
544
+									#else
545
+										warn("tls support not compiled in");
546
+									#endif
547
+									}
548
+		| TLS_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
533 549
 		| SERVER_SIGNATURE EQUAL NUMBER { server_signature=$3; }
534 550
 		| SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
535 551
 		| REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; }
... ...
@@ -71,6 +71,8 @@ extern int children_no;
71 71
 extern int tcp_children_no;
72 72
 extern int tcp_disable;
73 73
 extern int tcp_accept_aliases;
74
+extern int tcp_connect_timeout;
75
+extern int tcp_send_timeout;
74 76
 #endif
75 77
 #ifdef USE_TLS
76 78
 extern int tls_disable;
... ...
@@ -46,9 +46,10 @@
46 46
 #define TCP_BUF_SIZE 65535
47 47
 #define TCP_CON_TIMEOUT 120 /* in  seconds */
48 48
 #define TCP_CON_SEND_TIMEOUT 120 /* timeout after a send */
49
-#define TCP_SEND_TIMEOUT 10 /* if a send doesn't complete in 10s, timeout */
50
-#define TCP_CONNECT_TIMEOUT 10 /* if a connect doesn't complete in this time,
51
-                                  timeout */
49
+#define DEFAULT_TCP_SEND_TIMEOUT 10 /* if a send can't write for more then 10s,
50
+									   timeout */
51
+#define DEFAULT_TCP_CONNECT_TIMEOUT 10 /* if a connect doesn't complete in this
52
+										  time, timeout */
52 53
 #define TCP_CHILD_TIMEOUT 5 /* after 5 seconds, the child "returns" 
53 54
 							 the connection to the tcp master process */
54 55
 #define TCP_MAIN_SELECT_TIMEOUT 5 /* how often "tcp main" checks for timeout*/
... ...
@@ -76,6 +76,7 @@
76 76
 #include <netdb.h>
77 77
 
78 78
 #include <unistd.h>
79
+#include <fcntl.h>
79 80
 
80 81
 #include <errno.h>
81 82
 #include <string.h>
... ...
@@ -116,6 +117,8 @@ struct tcp_child{
116 116
 
117 117
 
118 118
 int tcp_accept_aliases=0; /* by default don't accept aliases */
119
+int tcp_connect_timeout=DEFAULT_TCP_CONNECT_TIMEOUT;
120
+int tcp_send_timeout=DEFAULT_TCP_SEND_TIMEOUT;
119 121
 
120 122
 /* connection hash table (after ip&port) , includes also aliases */
121 123
 struct tcp_conn_alias** tcpconn_aliases_hash=0;
... ...
@@ -132,6 +135,179 @@ int unix_tcp_sock;
132 132
 int tcp_proto_no=-1; /* tcp protocol number as returned by getprotobyname */
133 133
 
134 134
 
135
+
136
+/* set all socket/fd options:  disable nagle, tos lowdelay, non-blocking
137
+ * return -1 on error */
138
+static int init_sock_opt(int s)
139
+{
140
+	int flags;
141
+	int optval;
142
+	
143
+#ifdef DISABLE_NAGLE
144
+	flags=1;
145
+	if ( (tcp_proto_no!=-1) && (setsockopt(s, tcp_proto_no , TCP_NODELAY,
146
+					&flags, sizeof(flags))<0) ){
147
+		LOG(L_WARN, "WARNING: init_sock_opt: could not disable Nagle: %s\n",
148
+				strerror(errno));
149
+	}
150
+#endif
151
+	/* tos*/
152
+	optval=IPTOS_LOWDELAY;
153
+	if (setsockopt(s, IPPROTO_IP, IP_TOS, (void*)&optval,sizeof(optval)) ==-1){
154
+		LOG(L_WARN, "WARNING: init_sock_opt: setsockopt tos: %s\n",
155
+				strerror(errno));
156
+		/* continue since this is not critical */
157
+	}
158
+	/* non-blocking */
159
+	flags=fcntl(s, F_GETFL);
160
+	if (flags==-1){
161
+		LOG(L_ERR, "ERROR: init_sock_opt: fnctl failed: (%d) %s\n",
162
+				errno, strerror(errno));
163
+		goto error;
164
+	}
165
+	if (fcntl(s, F_SETFL, flags|O_NONBLOCK)==-1){
166
+		LOG(L_ERR, "ERROR: init_sock_opt: fcntl: set non-blocking failed:"
167
+				" (%d) %s\n", errno, strerror(errno));
168
+		goto error;
169
+	}
170
+	return 0;
171
+error:
172
+	return -1;
173
+}
174
+
175
+
176
+
177
+static int tcp_blocking_connect(int fd, const struct sockaddr *servaddr,
178
+								socklen_t addrlen)
179
+{
180
+	int n;
181
+	fd_set sel_set;
182
+	struct timeval timeout;
183
+	int ticks;
184
+	int err;
185
+	int err_len;
186
+	
187
+again:
188
+	n=connect(fd, servaddr, addrlen);
189
+	if (n==-1){
190
+		if (errno==EINTR) goto again;
191
+		if (errno!=EINPROGRESS && errno!=EALREADY){
192
+			LOG(L_ERR, "ERROR: tcp_blocking_connect: (%d) %s\n",
193
+					errno, strerror(errno));
194
+			goto error;
195
+		}
196
+	}else goto end;
197
+	
198
+	while(1){
199
+		FD_ZERO(&sel_set);
200
+		FD_SET(fd, &sel_set);
201
+		timeout.tv_sec=tcp_connect_timeout;
202
+		timeout.tv_usec=0;
203
+		ticks=get_ticks();
204
+		n=select(fd+1, 0, &sel_set, 0, &timeout);
205
+		if (n<0){
206
+			if (errno==EINTR) continue;
207
+			LOG(L_ERR, "ERROR: tcp_blocking_connect: select failed: (%d) %s\n",
208
+					errno, strerror(errno));
209
+			goto error;
210
+		}else if (n==0){
211
+			/* timeout */
212
+			if (get_ticks()-ticks>=tcp_connect_timeout){
213
+				LOG(L_ERR, "ERROR: tcp_blocking_connect: timeout (%d)\n",
214
+						tcp_connect_timeout);
215
+				goto error;
216
+			}
217
+			continue;
218
+		}
219
+		if (FD_ISSET(fd, &sel_set)){
220
+			err_len=sizeof(err);
221
+			getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &err_len);
222
+			if (err==0) goto end;
223
+			if (err!=EINPROGRESS && err!=EALREADY){
224
+				LOG(L_ERR, "ERROR: tcp_blocking_connect: SO_ERROR (%d) %s\n",
225
+						err, strerror(err));
226
+				goto error;
227
+			}
228
+		}
229
+	}
230
+error:
231
+	return -1;
232
+end:
233
+	return 0;
234
+}
235
+
236
+
237
+
238
+/* blocking write even on non-blocking sockets 
239
+ * if TCP_TIMEOUT will return with error */
240
+static int tcp_blocking_write(struct tcp_connection* c, int fd, char* buf,
241
+								unsigned int len)
242
+{
243
+	int n;
244
+	fd_set sel_set;
245
+	struct timeval timeout;
246
+	int ticks;
247
+	int initial_len;
248
+	
249
+	initial_len=len;
250
+again:
251
+	
252
+	n=send(fd, buf, len,
253
+#ifdef HAVE_MSG_NOSIGNAL
254
+			MSG_NOSIGNAL
255
+#else
256
+			0
257
+#endif
258
+		);
259
+	if (n<0){
260
+		if (errno==EINTR)	goto again;
261
+		else if (errno!=EAGAIN && errno!=EWOULDBLOCK){
262
+			LOG(L_ERR, "tcp_blocking_write: failed to send: (%d) %s\n",
263
+					errno, strerror(errno));
264
+			goto error;
265
+		}
266
+	}else if (n<len){
267
+		/* partial write */
268
+		buf+=n;
269
+		len-=n;
270
+	}else{
271
+		/* success: full write */
272
+		goto end;
273
+	}
274
+	while(1){
275
+		FD_ZERO(&sel_set);
276
+		FD_SET(fd, &sel_set);
277
+		timeout.tv_sec=tcp_send_timeout;
278
+		timeout.tv_usec=0;
279
+		ticks=get_ticks();
280
+		n=select(fd+1, 0, &sel_set, 0, &timeout);
281
+		if (n<0){
282
+			if (errno==EINTR) continue; /* signal, ignore */
283
+			LOG(L_ERR, "ERROR: tcp_blocking_write: select failed: "
284
+					" (%d) %s\n", errno, strerror(errno));
285
+			goto error;
286
+		}else if (n==0){
287
+			/* timeout */
288
+			if (get_ticks()-ticks>=tcp_send_timeout){
289
+				LOG(L_ERR, "ERROR: tcp_blocking_write: send timeout (%d)\n",
290
+						tcp_send_timeout);
291
+				goto error;
292
+			}
293
+			continue;
294
+		}
295
+		if (FD_ISSET(fd, &sel_set)){
296
+			/* we can write again */
297
+			goto again;
298
+		}
299
+	}
300
+error:
301
+		return -1;
302
+end:
303
+		return initial_len;
304
+}
305
+
306
+
307
+
135 308
 struct tcp_connection* tcpconn_new(int sock, union sockaddr_union* su,
136 309
 									struct socket_info* ba, int type, 
137 310
 									int state)
... ...
@@ -213,11 +389,7 @@ struct tcp_connection* tcpconn_connect(union sockaddr_union* server, int type)
213 213
 	struct socket_info* si;
214 214
 	union sockaddr_union my_name;
215 215
 	socklen_t my_name_len;
216
-	int optval;
217 216
 	struct tcp_connection* con;
218
-#ifdef DISABLE_NAGLE
219
-	int flag;
220
-#endif
221 217
 
222 218
 	s=socket(AF2PF(server->s.sa_family), SOCK_STREAM, 0);
223 219
 	if (s==-1){
... ...
@@ -225,25 +397,12 @@ struct tcp_connection* tcpconn_connect(union sockaddr_union* server, int type)
225 225
 				errno, strerror(errno));
226 226
 		goto error;
227 227
 	}
228
-#ifdef DISABLE_NAGLE
229
-	flag=1;
230
-	if ( (tcp_proto_no!=-1) && (setsockopt(s, tcp_proto_no , TCP_NODELAY,
231
-					&flag, sizeof(flag))<0) ){
232
-		LOG(L_ERR, "ERROR: tcp_connect: could not disable Nagle: %s\n",
233
-				strerror(errno));
234
-	}
235
-#endif
236
-	/* tos*/
237
-	optval=IPTOS_LOWDELAY;
238
-	if (setsockopt(s, IPPROTO_IP, IP_TOS, (void*)&optval, sizeof(optval)) ==-1){
239
-		LOG(L_WARN, "WARNING: tcpconn_connect: setsockopt tos: %s\n",
240
-				strerror(errno));
241
-		/* continue since this is not critical */
228
+	if (init_sock_opt(s)<0){
229
+		LOG(L_ERR, "ERROR: tcpconn_connect: init_sock_opt failed\n");
230
+		goto error;
242 231
 	}
243
-
244
-	if (connect(s, &server->s, sockaddru_len(*server))<0){
245
-		LOG(L_ERR, "ERROR: tcpconn_connect: connect: (%d) %s\n",
246
-				errno, strerror(errno));
232
+	if (tcp_blocking_connect(s, &server->s, sockaddru_len(*server))<0){
233
+		LOG(L_ERR, "ERROR: tcpconn_connect: tcp_blocking_connect failed\n");
247 234
 		goto error;
248 235
 	}
249 236
 	my_name_len=sizeof(my_name);
... ...
@@ -483,139 +642,6 @@ void tcpconn_put(struct tcp_connection* c)
483 483
 }
484 484
 
485 485
 
486
-static int tcp_blocking_connect(int fd, const struct sockaddr *servaddr,
487
-								socklen_t addrlen)
488
-{
489
-	int n;
490
-	fd_set sel_set;
491
-	struct timeval timeout;
492
-	int ticks;
493
-	int err;
494
-	int err_len;
495
-	
496
-again:
497
-	n=connect(fd, servaddr, addrlen);
498
-	if (n==-1){
499
-		if (errno==EINTR) goto again;
500
-		if (errno!=EINPROGRESS && errno!=EALREADY){
501
-			LOG(L_ERR, "ERROR: tcp_blocking_connect: (%d) %s\n",
502
-					errno, strerror(errno));
503
-			goto error;
504
-		}
505
-	}else goto end;
506
-	
507
-	while(1){
508
-		FD_ZERO(&sel_set);
509
-		FD_SET(fd, &sel_set);
510
-		timeout.tv_sec=TCP_CONNECT_TIMEOUT;
511
-		timeout.tv_usec=0;
512
-		ticks=get_ticks();
513
-		n=select(fd+1, 0, &sel_set, 0, &timeout);
514
-		if (n<0){
515
-			if (errno==EINTR) continue;
516
-			LOG(L_ERR, "ERROR: tcp_blocking_connect: select failed: (%d) %s\n",
517
-					errno, strerror(errno));
518
-			goto error;
519
-		}else if (n==0){
520
-			/* timeout */
521
-			if (get_ticks()-ticks>=TCP_CONNECT_TIMEOUT){
522
-				LOG(L_ERR, "ERROR: tcp_blocking_connect: send timeout\n");
523
-				goto error;
524
-			}
525
-			continue;
526
-		}
527
-		if (FD_ISSET(fd, &sel_set)){
528
-			err_len=sizeof(err);
529
-			getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &err_len);
530
-			if (err==0) goto end;
531
-			if (err!=EINPROGRESS && err!=EALREADY){
532
-				LOG(L_ERR, "ERROR: tcp_blocking_connect: SO_ERROR (%d) %s\n",
533
-						err, strerror(err));
534
-				goto error;
535
-			}
536
-		}
537
-	}
538
-error:
539
-	return -1;
540
-end:
541
-	return 0;
542
-}
543
-
544
-
545
-
546
-/* blocking write even on non-blocking sockets 
547
- * if TCP_TIMEOUT will return with error */
548
-static int tcp_blocking_write(struct tcp_connection* c, int fd, char* buf,
549
-								unsigned int len)
550
-{
551
-	int n;
552
-	fd_set sel_set;
553
-	struct timeval timeout;
554
-	int ticks;
555
-	int initial_len;
556
-	
557
-	initial_len=len;
558
-again:
559
-	/* try first without select */
560
-	if (c->state==S_CONN_CONNECT){
561
-		/* connect not finished,  try again ? */
562
-		LOG(L_CRIT, "BUG: tcp_blocking_write: connect not implemented yet\n");
563
-		goto error;
564
-	}
565
-	n=send(fd, buf, len,
566
-#ifdef HAVE_MSG_NOSIGNAL
567
-			MSG_NOSIGNAL
568
-#else
569
-			0
570
-#endif
571
-		);
572
-	if (n<0){
573
-		if (errno==EINTR)	goto again;
574
-		else if (errno!=EAGAIN && errno!=EWOULDBLOCK){
575
-			LOG(L_ERR, "tcp_blocking_write: failed to send: (%d) %s\n",
576
-					errno, strerror(errno));
577
-			goto error;
578
-		}
579
-	}else if (n<len){
580
-		/* partial write */
581
-		buf+=n;
582
-		len-=n;
583
-	}else{
584
-		/* success: full write */
585
-		goto end;
586
-	}
587
-	while(1){
588
-		FD_ZERO(&sel_set);
589
-		FD_SET(fd, &sel_set);
590
-		timeout.tv_sec=TCP_SEND_TIMEOUT;
591
-		timeout.tv_usec=0;
592
-		ticks=get_ticks();
593
-		n=select(fd+1, 0, &sel_set, 0, &timeout);
594
-		if (n<0){
595
-			if (errno==EINTR) continue; /* signal, ignore */
596
-			LOG(L_ERR, "ERROR: tcp_blocking_write: select failed: "
597
-					" (%d) %s\n", errno, strerror(errno));
598
-			goto error;
599
-		}else if (n==0){
600
-			/* timeout */
601
-			if (get_ticks()-ticks>=TCP_SEND_TIMEOUT){
602
-				LOG(L_ERR, "ERROR: tcp_blocking_write: send timeout\n");
603
-				goto error;
604
-			}
605
-			continue;
606
-		}
607
-		if (FD_ISSET(fd, &sel_set)){
608
-			/* we can write again */
609
-			goto again;
610
-		}
611
-	}
612
-error:
613
-		return -1;
614
-end:
615
-		return initial_len;
616
-}
617
-
618
-
619 486
 
620 487
 /* finds a tcpconn & sends on it */
621 488
 int tcp_send(int type, char* buf, unsigned len, union sockaddr_union* to,
... ...
@@ -730,21 +756,12 @@ send_it:
730 730
 		n=tls_blocking_write(c, fd, buf, len);
731 731
 	else
732 732
 #endif
733
-		n=send(fd, buf, len,
734
-#ifdef HAVE_MSG_NOSIGNAL
735
-			MSG_NOSIGNAL
736
-#else
737
-			0
738
-#endif
739
-			);
733
+		n=tcp_blocking_write(c, fd, buf, len);
740 734
 	lock_release(&c->write_lock);
741 735
 	DBG("tcp_send: after write: c= %p n=%d fd=%d\n",c, n, fd);
742 736
 	DBG("tcp_send: buf=\n%.*s\n", (int)len, buf);
743 737
 	if (n<0){
744
-		if (errno==EINTR) goto send_it; /* interrupted write, try again*/
745
-										/* keep the lock or lock/unlock again?*/
746
-		LOG(L_ERR, "ERROR: tcpsend: failed to send, n=%d: %s (%d)\n",
747
-				n, strerror(errno), errno);
738
+		LOG(L_ERR, "ERROR: tcp_send: failed to send\n");
748 739
 		/* error on the connection , mark it as bad and set 0 timeout */
749 740
 		c->state=S_CONN_BAD;
750 741
 		c->timeout=0;
... ...
@@ -959,6 +976,11 @@ static inline void handle_new_connect(struct socket_info* si,
959 959
 					" connection(%d): %s\n", errno, strerror(errno));
960 960
 			return;
961 961
 		}
962
+		if (init_sock_opt(new_sock)<0){
963
+			LOG(L_ERR, "ERROR: tcp_main_loop: init_sock_opt failed\n");
964
+			close(new_sock);
965
+			return;
966
+		}
962 967
 		
963 968
 		/* add socket to list */
964 969
 		tcpconn=tcpconn_new(new_sock, &su, si, si->proto, S_CONN_ACCEPT);