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 411
 	}
412 412
 	memset(&pp, 0, sizeof(pp)); /* zero everything we don't care about */
413 413
 	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");
414
+	err=0;
415
+	for (si=sctp_listen; si; si=si->next){
416
+		/* set the AF, needed on older linux kernels even for INADDR_ANY */
417
+		pp.spp_address.ss_family=si->address.af;
418
+		err+=(sctp_setsockopt(si->socket, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS,
419
+								(void*)(&pp), sizeof(pp),
420
+								"cfg: setting SCTP_PEER_ADDR_PARAMS")<0);
421
+	}
422
+	return -(err!=0);
416 423
 #else
417 424
 	ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
418 425
 			" 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 357
    only a limited number of sctp socket options)
358 358
    returns 0 on success, -1 on error
359 359
    WARNING: please keep it sync'ed w/ sctp_check_compiled_sockopts() */
360
-static int sctp_init_sock_opt_common(int s)
360
+static int sctp_init_sock_opt_common(int s, int af)
361 361
 {
362 362
 	int optval;
363 363
 	int pd_point;
... ...
@@ -596,6 +598,7 @@ static int sctp_init_sock_opt_common(int s)
596 596
 	/* set sctp peer addr options: hbinterval & pathmaxrxt */
597 597
 #ifdef SCTP_PEER_ADDR_PARAMS
598 598
 	memset(&pp, 0, sizeof(pp));
599
+	pp.spp_address.ss_family=af;
599 600
 	pp.spp_hbinterval=cfg_get(sctp, sctp_cfg, hbinterval);
600 601
 	pp.spp_pathmaxrxt=cfg_get(sctp, sctp_cfg, pathmaxrxt);
601 602
 	if (pp.spp_hbinterval || pp.spp_pathmaxrxt){
... ...
@@ -804,7 +807,7 @@ int sctp_init_sock(struct socket_info* sock_info)
804 804
 #endif
805 805
 
806 806
 	/* set sock opts */
807
-	if (sctp_init_sock_opt_common(sock_info->socket)!=0)
807
+	if (sctp_init_sock_opt_common(sock_info->socket, sock_info->address.af)!=0)
808 808
 		goto error;
809 809
 	/* SCTP_EVENTS for send dried out -> present in the draft not yet
810 810
 	 * 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 862
 	}
863 863
 	
864 864
 	/* set sock opts */
865
-	if (sctp_init_sock_opt_common(sock_info->socket)!=0)
865
+	if (sctp_init_sock_opt_common(sock_info->socket, sock_info->address.af)!=0)
866 866
 		goto error;
867 867
 	
868 868
 #ifdef SCTP_REUSE_PORT