Browse code

- changed tcp timeouts to 3 min idle after receive and 2 min after a send backported fixes: - tcp conn id fix to stable - acc mem. leak - dns mem. leak (resolve.c) - id_builder receive_msg mem. leak (msg_translator.c) - check_self ipv6 + case insensitive matching (forward.c)

Andrei Pelinescu-Onciul authored on 22/08/2003 16:31:06
Showing 6 changed files
... ...
@@ -40,7 +40,7 @@ export makefile_defs
40 40
 VERSION = 0
41 41
 PATCHLEVEL = 8
42 42
 SUBLEVEL =   11
43
-EXTRAVERSION = rc3
43
+EXTRAVERSION = rc4
44 44
 
45 45
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
46 46
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")
... ...
@@ -41,6 +41,7 @@
41 41
  *               local replies  & "normal" replies (andrei)
42 42
  *  2003-04-12  update_sock_struct_form via uses also FL_FORCE_RPORT for
43 43
  *               local replies (andrei)
44
+ *  2003-08-21  check_self properly handles ipv6 addresses & refs   (andrei)
44 45
  */
45 46
 
46 47
 
... ...
@@ -205,46 +206,67 @@ struct socket_info* get_send_socket(union sockaddr_union* to, int proto)
205 206
 /* checks if the host:port is one of the address we listen on;
206 207
  * if port==0, the  port number is ignored
207 208
  * returns 1 if true, 0 if false, -1 on error
208
-*/
209
+ * WARNING: uses str2ip6 so it will overwrite any previous
210
+ *  unsaved result of this function (static buffer)
211
+ */
209 212
 int check_self(str* host, unsigned short port)
210 213
 {
211 214
 	int r;
215
+	char* hname;
216
+	int h_len;
217
+#ifdef USE_IPV6
218
+	struct ip_addr* ip6;
219
+#endif
212 220
 	
221
+	h_len=host->len;
222
+	hname=host->s;
223
+#ifdef USE_IPV6
224
+	if ((h_len>2)&&((*hname)=='[')&&(hname[h_len-1]==']')){
225
+		/* ipv6 reference, skip [] */
226
+		hname++;
227
+		h_len-=2;
228
+	}
229
+#endif
213 230
 	for (r=0; r<sock_no; r++){
214 231
 		DBG("check_self - checking if host==us: %d==%d && "
215 232
 				" [%.*s] == [%.*s]\n", 
216
-					host->len,
233
+					h_len,
217 234
 					sock_info[r].name.len,
218
-					host->len, host->s,
235
+					h_len, hname,
219 236
 					sock_info[r].name.len, sock_info[r].name.s
220 237
 			);
221
-		if  ((port)&&(sock_info[r].port_no!=port)) continue;
222
-		if ( (host->len==sock_info[r].name.len) && 
223
-	#ifdef USE_IPV6
224
-			(strncasecmp(host->s, sock_info[r].name.s,
225
-								 sock_info[r].name.len)==0) /*slower*/
226
-	#else
227
-			(memcmp(host->s, sock_info[r].name.s, 
228
-								sock_info[r].name.len)==0)
229
-	#endif
230
-			)
238
+		if ((port) && (sock_info[r].port_no!=port))
239
+			continue;
240
+		if ( (h_len==sock_info[r].name.len) && 
241
+			(strncasecmp(hname, sock_info[r].name.s,
242
+				     sock_info[r].name.len)==0) /*slower*/)
243
+			/* comp. must be case insensitive, host names
244
+			 * can be written in mixed case, it will also match
245
+			 * ipv6 addresses if we are lucky*/
231 246
 			break;
232 247
 	/* check if host == ip address */
248
+#ifdef USE_IPV6
249
+		/* ipv6 case is uglier, host can be [3ffe::1] */
250
+		ip6=str2ip6(host);
251
+		if (ip6){
252
+			if (ip_addr_cmp(ip6, &sock_info[r].address))
253
+				break; /* match */
254
+			else
255
+				continue; /* no match, but this is an ipv6 address
256
+							 so no point in trying ipv4 */
257
+		}
258
+#endif
259
+		/* ipv4 */
233 260
 		if ( 	(!sock_info[r].is_ip) &&
234
-				(host->len==sock_info[r].address_str.len) && 
235
-	#ifdef USE_IPV6
236
-			(strncasecmp(host->s, sock_info[r].address_str.s,
237
-								 sock_info[r].address_str.len)==0) /*slower*/
238
-	#else
239
-			(memcmp(host->s, sock_info[r].address_str.s, 
261
+				(h_len==sock_info[r].address_str.len) && 
262
+			(memcmp(hname, sock_info[r].address_str.s, 
240 263
 								sock_info[r].address_str.len)==0)
241
-	#endif
242 264
 			)
243 265
 			break;
244 266
 	}
245 267
 	if (r==sock_no){
246 268
 		/* try to look into the aliases*/
247
-		if (grep_aliases(host->s, host->len, port)==0){
269
+		if (grep_aliases(hname, h_len, port)==0){
248 270
 			DBG("check_self: host != me\n");
249 271
 			return 0;
250 272
 		}
... ...
@@ -1182,7 +1182,8 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1182 1182
 		if  ((id_buf=id_builder(msg, &id_len))==0){
1183 1183
 			LOG(L_ERR, "ERROR: build_req_buf_from_sip_req:"
1184 1184
 							" id_builder failed\n");
1185
-			goto error01; /* free everything */
1185
+			goto error00; /* we don't need to free anything,
1186
+			                 nothing alloc'ed yet*/
1186 1187
 		}
1187 1188
 		extra_params.s=id_buf;
1188 1189
 		extra_params.len=id_len;
... ...
@@ -1303,7 +1304,7 @@ skip_clen:
1303 1304
 		 * parse_headers is called from clen_builder */
1304 1305
 		anchor=anchor_lump(&(msg->add_rm), msg->unparsed-buf, 0,
1305 1306
 							 HDR_CONTENTLENGTH);
1306
-		if (anchor==0) goto error04; /* free clen_buf*/
1307
+		if (anchor==0) goto error04; /* free clen_buf */
1307 1308
 		if (insert_new_lump_after(anchor, clen_buf, clen_len,
1308 1309
 					HDR_CONTENTLENGTH)==0)
1309 1310
 			goto error04; /* free clen_buf*/
... ...
@@ -1354,13 +1355,15 @@ skip_clen:
1354 1355
 #endif
1355 1356
 
1356 1357
 	*returned_len=new_len;
1358
+	/* cleanup */
1359
+#ifdef USE_TCP
1360
+	if (id_buf) pkg_free(id_buf); /* it's not in a lump => we don't need it
1361
+									 anymore */
1362
+#endif
1357 1363
 	return new_buf;
1358 1364
 
1359 1365
 error01:
1360
-	pkg_free(line_buf);
1361
-#ifdef USE_TCP
1362
-	if (id_buf) pkg_free(id_buf);
1363
-#endif
1366
+	if (line_buf) pkg_free(line_buf);
1364 1367
 error02:
1365 1368
 	if (received_buf) pkg_free(received_buf);
1366 1369
 error03:
... ...
@@ -1370,6 +1373,9 @@ error04:
1370 1373
 	if (clen_buf) pkg_free(clen_buf);
1371 1374
 #endif
1372 1375
 error00:
1376
+#ifdef USE_TCP
1377
+	if (id_buf) pkg_free(id_buf);
1378
+#endif
1373 1379
 	*returned_len=0;
1374 1380
 	return 0;
1375 1381
 }
... ...
@@ -522,7 +522,8 @@ struct hostent* sip_resolvehost(str* name, unsigned short* port, int proto)
522 522
 					return he;
523 523
 				}
524 524
 			}
525
-			DBG("sip_resolvehost: not SRV record found for %.*s," 
525
+			if (head) free_rdata_list(head); /*clean up*/
526
+			DBG("sip_resolvehost: no SRV record found for %.*s," 
526 527
 					" trying 'normal' lookup...\n", name->len, name->s);
527 528
 		}
528 529
 	}
... ...
@@ -41,12 +41,12 @@
41 41
 
42 42
 
43 43
 #define TCP_BUF_SIZE 65535
44
-#define TCP_CON_TIMEOUT 60 /* in  seconds */
45
-#define TCP_CON_SEND_TIMEOUT 30 /* timeout after a send */
46
-#define TCP_CHILD_TIMEOUT 5 /* after 5 seconds, the child "returns" 
44
+#define TCP_CON_TIMEOUT 180 /* in  seconds */
45
+#define TCP_CON_SEND_TIMEOUT 120 /* timeout after a send */
46
+#define TCP_CHILD_TIMEOUT 10 /* after 5 seconds, the child "returns" 
47 47
 							 the connection to the tcp master process */
48
-#define TCP_MAIN_SELECT_TIMEOUT 5 /* how often "tcp main" checks for timeout*/
49
-#define TCP_CHILD_SELECT_TIMEOUT 2 /* the same as above but for children */
48
+#define TCP_MAIN_SELECT_TIMEOUT 10 /* how often "tcp main" checks for timeout*/
49
+#define TCP_CHILD_SELECT_TIMEOUT 5 /* the same as above but for children */
50 50
 
51 51
 
52 52
 enum tcp_req_errors {	TCP_REQ_INIT, TCP_REQ_OK, TCP_READ_ERROR,
... ...
@@ -106,7 +106,7 @@ struct tcp_connection** tcpconn_id_hash=0;
106 106
 gen_lock_t* tcpconn_lock=0;
107 107
 
108 108
 struct tcp_child tcp_children[MAX_TCP_CHILDREN];
109
-static int connection_id=1; /*  unique for each connection, used for 
109
+static int* connection_id=0; /*  unique for each connection, used for 
110 110
 								quickly finding the corresponding connection
111 111
 								for a reply */
112 112
 int unix_tcp_sock;
... ...
@@ -147,7 +147,7 @@ struct tcp_connection* tcpconn_new(int sock, union sockaddr_union* su,
147 147
 	}
148 148
 	init_tcp_req(&c->req);
149 149
 	c->timeout=get_ticks()+TCP_CON_TIMEOUT;
150
-	c->id=connection_id++;
150
+	c->id=(*connection_id)++;
151 151
 	c->rcv.proto_reserved1=0; /* this will be filled before receive_message*/
152 152
 	c->rcv.proto_reserved2=0;
153 153
 	return c;
... ...
@@ -872,12 +872,24 @@ int init_tcp()
872 872
 		tcpconn_lock=0;
873 873
 		goto error;
874 874
 	}
875
+	/* init globals */
876
+	connection_id=(int*)shm_malloc(sizeof(int));
877
+	if (connection_id==0){
878
+		LOG(L_CRIT, "ERROR: init_tcp: could not alloc globals\n");
879
+		lock_destroy(tcpconn_lock);
880
+		lock_dealloc((void*)tcpconn_lock);
881
+		tcpconn_lock=0;
882
+		goto error;
883
+	}
884
+	*connection_id=1;
875 885
 	/* alloc hashtables*/
876 886
 	tcpconn_addr_hash=(struct tcp_connection**)shm_malloc(TCP_ADDR_HASH_SIZE*
877 887
 								sizeof(struct tcp_connection*));
878 888
 
879 889
 	if (tcpconn_addr_hash==0){
880 890
 		LOG(L_CRIT, "ERROR: init_tcp: could not alloc address hashtable\n");
891
+		shm_free(connection_id);
892
+		connection_id=0;
881 893
 		lock_destroy(tcpconn_lock);
882 894
 		lock_dealloc((void*)tcpconn_lock);
883 895
 		tcpconn_lock=0;
... ...
@@ -888,6 +900,8 @@ int init_tcp()
888 900
 								sizeof(struct tcp_connection*));
889 901
 	if (tcpconn_id_hash==0){
890 902
 		LOG(L_CRIT, "ERROR: init_tcp: could not alloc id hashtable\n");
903
+		shm_free(connection_id);
904
+		connection_id=0;
891 905
 		shm_free(tcpconn_addr_hash);
892 906
 		tcpconn_addr_hash=0;
893 907
 		lock_destroy(tcpconn_lock);
... ...
@@ -923,6 +937,10 @@ void destroy_tcp()
923 937
 		shm_free(tcpconn_id_hash);
924 938
 		tcpconn_id_hash=0;
925 939
 	}
940
+	if(connection_id){
941
+		shm_free(connection_id);
942
+		connection_id=0;
943
+	}
926 944
 }
927 945
 
928 946