Browse code

sctp: SCTP_PEER_ADDR_PARAMS fix for older kernels

On older kernels (< 2.6.27) one has to set the AF when setting a
SCTP_PEER_ADDR_PARAMS socket option even if the address is the
wildcard (INADDR_ANY).
This affects the sctp_hbinterval and sctp_pathmaxrxt config
options.

Reported-by: Cristian Constantin <cristian.constantin@iptel.org>

Andrei Pelinescu-Onciul authored on 17/06/2009 09:12:08
Showing 2 changed files
... ...
@@ -387,8 +387,15 @@ static int set_hbinterval(void* cfg_h, str* gname, str* name,
387 387
 	}else{
388 388
 		pp.spp_flags=SPP_HB_DISABLE;
389 389
 	}
390
-	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, pp,
391
-							"cfg: setting SCTP_PEER_ADDR_PARAMS");
390
+	err=0;
391
+	for (si=sctp_listen; si; si=si->next){
392
+		/* set the AF, needed on older linux kernels even for INADDR_ANY */
393
+		pp.spp_address.ss_family=si->address.af;
394
+		err+=(sctp_setsockopt(si->socket, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS,
395
+								(void*)(&pp), sizeof(pp),
396
+								"cfg: setting SCTP_PEER_ADDR_PARAMS")<0);
397
+	}
398
+	return -(err!=0);
392 399
 #else
393 400
 	ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
394 401
 			" sctp library\n");
... ...
@@ -411,8 +418,15 @@ static int set_pathmaxrxt(void* cfg_h, str* gname, str* name,
411 418
 	}
412 419
 	memset(&pp, 0, sizeof(pp)); /* zero everything we don't care about */
413 420
 	pp.spp_pathmaxrxt=(int)(long)(*val);
414
-	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, pp,
415
-							"cfg: setting SCTP_PEER_ADDR_PARAMS");
421
+	err=0;
422
+	for (si=sctp_listen; si; si=si->next){
423
+		/* set the AF, needed on older linux kernels even for INADDR_ANY */
424
+		pp.spp_address.ss_family=si->address.af;
425
+		err+=(sctp_setsockopt(si->socket, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS,
426
+								(void*)(&pp), sizeof(pp),
427
+								"cfg: setting SCTP_PEER_ADDR_PARAMS")<0);
428
+	}
429
+	return -(err!=0);
416 430
 #else
417 431
 	ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
418 432
 			" sctp library\n");
... ...
@@ -309,6 +309,8 @@ int sctp_get_os_defaults(struct cfg_group_sctp* cfg)
309 309
 #ifdef SCTP_PEER_ADDR_PARAMS
310 310
 	optlen=sizeof(pp);
311 311
 	memset(&pp, 0, sizeof(pp)); /* get defaults */
312
+	/* set the AF, needed on older linux kernels even for INADDR_ANY */
313
+	pp.spp_address.ss_family=AF_INET;
312 314
 	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, (void*)&pp,
313 315
 							&optlen, "SCTP_PEER_ADDR_PARAMS")==0){
314 316
 		/* success => hack to set the "default" values*/
... ...
@@ -357,7 +359,7 @@ int sctp_get_os_defaults(struct cfg_group_sctp* cfg)
357 359
    only a limited number of sctp socket options)
358 360
    returns 0 on success, -1 on error
359 361
    WARNING: please keep it sync'ed w/ sctp_check_compiled_sockopts() */
360
-static int sctp_init_sock_opt_common(int s)
362
+static int sctp_init_sock_opt_common(int s, int af)
361 363
 {
362 364
 	int optval;
363 365
 	int pd_point;
... ...
@@ -596,6 +598,7 @@ static int sctp_init_sock_opt_common(int s)
596 598
 	/* set sctp peer addr options: hbinterval & pathmaxrxt */
597 599
 #ifdef SCTP_PEER_ADDR_PARAMS
598 600
 	memset(&pp, 0, sizeof(pp));
601
+	pp.spp_address.ss_family=af;
599 602
 	pp.spp_hbinterval=cfg_get(sctp, sctp_cfg, hbinterval);
600 603
 	pp.spp_pathmaxrxt=cfg_get(sctp, sctp_cfg, pathmaxrxt);
601 604
 	if (pp.spp_hbinterval || pp.spp_pathmaxrxt){
... ...
@@ -804,7 +807,7 @@ int sctp_init_sock(struct socket_info* sock_info)
804 807
 #endif
805 808
 
806 809
 	/* set sock opts */
807
-	if (sctp_init_sock_opt_common(sock_info->socket)!=0)
810
+	if (sctp_init_sock_opt_common(sock_info->socket, sock_info->address.af)!=0)
808 811
 		goto error;
809 812
 	/* SCTP_EVENTS for send dried out -> present in the draft not yet
810 813
 	 * present in linux (might help to detect when we could send again to
... ...
@@ -862,7 +865,7 @@ int sctp_init_sock_oo(struct socket_info* sock_info)
862 865
 	}
863 866
 	
864 867
 	/* set sock opts */
865
-	if (sctp_init_sock_opt_common(sock_info->socket)!=0)
868
+	if (sctp_init_sock_opt_common(sock_info->socket, sock_info->address.af)!=0)
866 869
 		goto error;
867 870
 	
868 871
 #ifdef SCTP_REUSE_PORT