diff --git a/openair2/COMMON/sctp_messages_types.h b/openair2/COMMON/sctp_messages_types.h index 88790bdc1f..313cdfa899 100644 --- a/openair2/COMMON/sctp_messages_types.h +++ b/openair2/COMMON/sctp_messages_types.h @@ -128,14 +128,7 @@ typedef struct sctp_data_ind_s { } sctp_data_ind_t; typedef struct sctp_init_s { - /* Request usage of ipv4 */ - unsigned ipv4:1; - /* Request usage of ipv6 */ - unsigned ipv6:1; - uint8_t nb_ipv4_addr; - uint32_t ipv4_address[10]; - uint8_t nb_ipv6_addr; - char *ipv6_address[10]; + char *bind_address; uint16_t port; uint32_t ppid; } sctp_init_t; diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 1c9ff19bff..ad1cd8f4ab 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -1873,21 +1873,15 @@ void cuup_init_n3(instance_t instance) void cucp_task_send_sctp_init_req(instance_t instance, char *my_addr) { - LOG_I(E1AP, "E1AP_CUCP_SCTP_REQ(create socket)\n"); - MessageDef *message_p = NULL; - message_p = itti_alloc_new_message (TASK_CUCP_E1, 0, SCTP_INIT_MSG); - message_p->ittiMsg.sctp_init.port = E1AP_PORT_NUMBER; - message_p->ittiMsg.sctp_init.ppid = E1AP_SCTP_PPID; - message_p->ittiMsg.sctp_init.ipv4 = 1; - message_p->ittiMsg.sctp_init.ipv6 = 0; - message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1; - message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(my_addr); - /* - * SR WARNING: ipv6 multi-homing fails sometimes for localhost. - * * * * Disable it for now. - */ - message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0; - message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1"; + size_t addr_len = strlen(my_addr) + 1; + LOG_I(E1AP, "E1AP_CUCP_SCTP_REQ(create socket) for %s len %ld\n", my_addr, addr_len); + MessageDef *message_p = itti_alloc_new_message_sized(TASK_CUCP_E1, 0, SCTP_INIT_MSG, sizeof(sctp_init_t) + addr_len); + sctp_init_t *init = &SCTP_INIT_MSG(message_p); + init->port = E1AP_PORT_NUMBER; + init->ppid = E1AP_SCTP_PPID; + char *addr_buf = (char *) (init + 1); // address after sctp_init ITTI message end, allocated above + init->bind_address = addr_buf; + memcpy(addr_buf, my_addr, addr_len); itti_send_msg_to_task(TASK_SCTP, instance, message_p); } diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index 8401b44eca..2731fa8e0b 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -96,25 +96,20 @@ static void cu_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *s AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } -static void cu_task_send_sctp_init_req(instance_t instance, char *my_addr) { +static void cu_task_send_sctp_init_req(instance_t instance, char *my_addr) +{ // 1. get the itti msg, and retrive the nb_id from the message // 2. use RC.rrc[nb_id] to fill the sctp_init_t with the ip, port // 3. creat an itti message to init - LOG_I(F1AP, "F1AP_CU_SCTP_REQ(create socket)\n"); - MessageDef *message_p = NULL; - message_p = itti_alloc_new_message (TASK_CU_F1, 0, SCTP_INIT_MSG); - message_p->ittiMsg.sctp_init.port = F1AP_PORT_NUMBER; - message_p->ittiMsg.sctp_init.ppid = F1AP_SCTP_PPID; - message_p->ittiMsg.sctp_init.ipv4 = 1; - message_p->ittiMsg.sctp_init.ipv6 = 0; - message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1; - message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(my_addr); - /* - * SR WARNING: ipv6 multi-homing fails sometimes for localhost. - * * * * Disable it for now. - */ - message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0; - message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1"; + size_t addr_len = strlen(my_addr) + 1; + LOG_I(F1AP, "F1AP_CU_SCTP_REQ(create socket) for %s len %ld\n", my_addr, addr_len); + MessageDef *message_p = itti_alloc_new_message_sized(TASK_CU_F1, 0, SCTP_INIT_MSG, sizeof(sctp_init_t) + addr_len); + sctp_init_t *init = &SCTP_INIT_MSG(message_p); + init->port = F1AP_PORT_NUMBER; + init->ppid = F1AP_SCTP_PPID; + char *addr_buf = (char *) (init + 1); // address after ITTI message end, allocated above + init->bind_address = addr_buf; + memcpy(addr_buf, my_addr, addr_len); itti_send_msg_to_task(TASK_SCTP, instance, message_p); } diff --git a/openair2/M2AP/m2ap_MCE.c b/openair2/M2AP/m2ap_MCE.c index 4a69e0c6d3..f3d2fb2e7a 100644 --- a/openair2/M2AP/m2ap_MCE.c +++ b/openair2/M2AP/m2ap_MCE.c @@ -227,29 +227,16 @@ int m2ap_MCE_init_sctp (m2ap_MCE_instance_t *instance_p, net_ip_address_t *local_ip_addr, uint32_t mce_port_for_M2C) { // Create and alloc new message - MessageDef *message; - sctp_init_t *sctp_init = NULL; DevAssert(instance_p != NULL); DevAssert(local_ip_addr != NULL); - message = itti_alloc_new_message (TASK_M2AP_MCE, 0, SCTP_INIT_MSG_MULTI_REQ); - sctp_init = &message->ittiMsg.sctp_init_multi; + size_t addr_len = strlen(local_ip_addr->ipv4_address) + 1; + MessageDef *message = itti_alloc_new_message_sized(TASK_M2AP_MCE, 0, SCTP_INIT_MSG_MULTI_REQ, sizeof(sctp_init_t) + addr_len); + sctp_init_t *sctp_init = &message->ittiMsg.sctp_init_multi; sctp_init->port = mce_port_for_M2C; sctp_init->ppid = M2AP_SCTP_PPID; - sctp_init->ipv4 = 1; - sctp_init->ipv6 = 0; - sctp_init->nb_ipv4_addr = 1; -#if 0 - memcpy(&sctp_init->ipv4_address, - local_ip_addr, - sizeof(*local_ip_addr)); -#endif - sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address); - /* - * SR WARNING: ipv6 multi-homing fails sometimes for localhost. - * * * * Disable it for now. - */ - sctp_init->nb_ipv6_addr = 0; - sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1"; + char *addr_buf = (char *) (sctp_init + 1); + sctp_init->bind_address = addr_buf; + memcpy(addr_buf, local_ip_addr->ipv4_address, addr_len); return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message); } @@ -502,41 +489,16 @@ void MCE_task_send_sctp_init_req(instance_t enb_id, m2ap_mce_sctp_req_t * m2ap_m // 2. use RC.rrc[enb_id] to fill the sctp_init_t with the ip, port // 3. creat an itti message to init - LOG_I(M2AP, "M2AP_SCTP_REQ(create socket)\n"); - MessageDef *message_p = NULL; - - message_p = itti_alloc_new_message (TASK_M2AP_MCE, 0, SCTP_INIT_MSG); - - // if( m2ap_mce_sctp_req == NULL ){ - // message_p->ittiMsg.sctp_init.port = M2AP_PORT_NUMBER; - // message_p->ittiMsg.sctp_init.ppid = M2AP_SCTP_PPID; - // message_p->ittiMsg.sctp_init.ipv4 = 1; - // message_p->ittiMsg.sctp_init.ipv6 = 0; - // message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1; - // //message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr); - // message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr("127.0.0.7"); - // /* - // * SR WARNING: ipv6 multi-homing fails sometimes for localhost. - // * * * * Disable it for now. - // */ - // message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0; - // message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1"; - // }else{ - message_p->ittiMsg.sctp_init.port = m2ap_mce_sctp_req->mce_port_for_M2C; - message_p->ittiMsg.sctp_init.ppid = M2AP_SCTP_PPID; - message_p->ittiMsg.sctp_init.ipv4 = 1; - message_p->ittiMsg.sctp_init.ipv6 = 0; - message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1; - //message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr); - message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(m2ap_mce_sctp_req->mce_m2_ip_address.ipv4_address); - /* - * SR WARNING: ipv6 multi-homing fails sometimes for localhost. - * * * * Disable it for now. - */ - message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0; - message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1"; - // } + size_t addr_len = strlen(m2ap_mce_sctp_req->mce_m2_ip_address.ipv4_address) + 1; + LOG_I(M2AP, "M2AP_SCTP_REQ(create socket) for %s len %ld\n", m2ap_mce_sctp_req->mce_m2_ip_address.ipv4_address, addr_len); + MessageDef *message_p = itti_alloc_new_message_sized (TASK_M2AP_MCE, 0, SCTP_INIT_MSG, sizeof(sctp_init_t) + addr_len); + sctp_init_t *init = &SCTP_INIT_MSG(message_p); + init->port = m2ap_mce_sctp_req->mce_port_for_M2C; + init->ppid = M2AP_SCTP_PPID; + char *addr_buf = (char *) (init + 1); // address after ITTI message end, allocated above + init->bind_address = addr_buf; + memcpy(addr_buf, m2ap_mce_sctp_req->mce_m2_ip_address.ipv4_address, addr_len); itti_send_msg_to_task(TASK_SCTP, enb_id, message_p); } diff --git a/openair2/M2AP/m2ap_eNB.c b/openair2/M2AP/m2ap_eNB.c index 4f17dbbb5a..c492778603 100644 --- a/openair2/M2AP/m2ap_eNB.c +++ b/openair2/M2AP/m2ap_eNB.c @@ -229,29 +229,16 @@ int m2ap_eNB_init_sctp (m2ap_eNB_instance_t *instance_p, net_ip_address_t *local_ip_addr, uint32_t enb_port_for_M2C) { // Create and alloc new message - MessageDef *message; - sctp_init_t *sctp_init = NULL; DevAssert(instance_p != NULL); DevAssert(local_ip_addr != NULL); - message = itti_alloc_new_message (TASK_M2AP_ENB, 0, SCTP_INIT_MSG_MULTI_REQ); - sctp_init = &message->ittiMsg.sctp_init_multi; + size_t addr_len = strlen(local_ip_addr->ipv4_address) + 1; + MessageDef *message = itti_alloc_new_message_sized(TASK_M2AP_ENB, 0, SCTP_INIT_MSG_MULTI_REQ, sizeof(sctp_init_t) + addr_len); + sctp_init_t *sctp_init = &message->ittiMsg.sctp_init_multi; sctp_init->port = enb_port_for_M2C; sctp_init->ppid = M2AP_SCTP_PPID; - sctp_init->ipv4 = 1; - sctp_init->ipv6 = 0; - sctp_init->nb_ipv4_addr = 1; -#if 0 - memcpy(&sctp_init->ipv4_address, - local_ip_addr, - sizeof(*local_ip_addr)); -#endif - sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address); - /* - * SR WARNING: ipv6 multi-homing fails sometimes for localhost. - * * * * Disable it for now. - */ - sctp_init->nb_ipv6_addr = 0; - sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1"; + char *addr_buf = (char *) (sctp_init + 1); + sctp_init->bind_address = addr_buf; + memcpy(addr_buf, local_ip_addr->ipv4_address, addr_len); return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message); } diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index 42cd577727..d0d2b03304 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -217,29 +217,16 @@ int x2ap_eNB_init_sctp (x2ap_eNB_instance_t *instance_p, net_ip_address_t *local_ip_addr, uint32_t enb_port_for_X2C) { // Create and alloc new message - MessageDef *message; - sctp_init_t *sctp_init = NULL; DevAssert(instance_p != NULL); DevAssert(local_ip_addr != NULL); - message = itti_alloc_new_message (TASK_X2AP, 0, SCTP_INIT_MSG_MULTI_REQ); - sctp_init = &message->ittiMsg.sctp_init_multi; + size_t addr_len = strlen(local_ip_addr->ipv4_address) + 1; + MessageDef *message = itti_alloc_new_message_sized(TASK_X2AP, 0, SCTP_INIT_MSG_MULTI_REQ, sizeof(sctp_init_t) + addr_len); + sctp_init_t *sctp_init = &message->ittiMsg.sctp_init_multi; sctp_init->port = enb_port_for_X2C; sctp_init->ppid = X2AP_SCTP_PPID; - sctp_init->ipv4 = 1; - sctp_init->ipv6 = 0; - sctp_init->nb_ipv4_addr = 1; -#if 0 - memcpy(&sctp_init->ipv4_address, - local_ip_addr, - sizeof(*local_ip_addr)); -#endif - sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address); - /* - * SR WARNING: ipv6 multi-homing fails sometimes for localhost. - * * * * Disable it for now. - */ - sctp_init->nb_ipv6_addr = 0; - sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1"; + char *addr_buf = (char *) (sctp_init + 1); + sctp_init->bind_address = addr_buf; + memcpy(addr_buf, local_ip_addr->ipv4_address, addr_len); return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message); } diff --git a/openair3/M3AP/m3ap_MCE.c b/openair3/M3AP/m3ap_MCE.c index 58f8c969a2..141ee09b4e 100644 --- a/openair3/M3AP/m3ap_MCE.c +++ b/openair3/M3AP/m3ap_MCE.c @@ -225,29 +225,16 @@ int m3ap_MCE_init_sctp (m3ap_MCE_instance_t *instance_p, net_ip_address_t *local_ip_addr, uint32_t mce_port_for_M3C) { // Create and alloc new message - MessageDef *message; - sctp_init_t *sctp_init = NULL; DevAssert(instance_p != NULL); DevAssert(local_ip_addr != NULL); - message = itti_alloc_new_message (TASK_M3AP_MCE, 0, SCTP_INIT_MSG_MULTI_REQ); - sctp_init = &message->ittiMsg.sctp_init_multi; + size_t addr_len = strlen(local_ip_addr->ipv4_address) + 1; + MessageDef *message = itti_alloc_new_message_sized(TASK_M3AP_MCE, 0, SCTP_INIT_MSG_MULTI_REQ, sizeof(sctp_init_t) + addr_len); + sctp_init_t *sctp_init = &message->ittiMsg.sctp_init_multi; sctp_init->port = mce_port_for_M3C; sctp_init->ppid = M3AP_SCTP_PPID; - sctp_init->ipv4 = 1; - sctp_init->ipv6 = 0; - sctp_init->nb_ipv4_addr = 1; -#if 0 - memcpy(&sctp_init->ipv4_address, - local_ip_addr, - sizeof(*local_ip_addr)); -#endif - sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address); - /* - * SR WARNING: ipv6 multi-homing fails sometimes for localhost. - * * * * Disable it for now. - */ - sctp_init->nb_ipv6_addr = 0; - sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1"; + char *addr_buf = (char *) (sctp_init + 1); + sctp_init->bind_address = addr_buf; + memcpy(addr_buf, local_ip_addr->ipv4_address, addr_len); return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message); } diff --git a/openair3/M3AP/m3ap_MME.c b/openair3/M3AP/m3ap_MME.c index 523737184e..892a210ffd 100644 --- a/openair3/M3AP/m3ap_MME.c +++ b/openair3/M3AP/m3ap_MME.c @@ -227,29 +227,16 @@ int m3ap_MME_init_sctp (m3ap_MME_instance_t *instance_p, net_ip_address_t *local_ip_addr, uint32_t mme_port_for_M3C) { // Create and alloc new message - MessageDef *message; - sctp_init_t *sctp_init = NULL; DevAssert(instance_p != NULL); DevAssert(local_ip_addr != NULL); - message = itti_alloc_new_message (TASK_M3AP_MME, 0, SCTP_INIT_MSG_MULTI_REQ); - sctp_init = &message->ittiMsg.sctp_init_multi; + size_t addr_len = strlen(local_ip_addr->ipv4_address) + 1; + MessageDef *message = itti_alloc_new_message_sized(TASK_M3AP_MME, 0, SCTP_INIT_MSG_MULTI_REQ, sizeof(sctp_init_t) + addr_len); + sctp_init_t *sctp_init = &message->ittiMsg.sctp_init_multi; sctp_init->port = mme_port_for_M3C; sctp_init->ppid = M3AP_SCTP_PPID; - sctp_init->ipv4 = 1; - sctp_init->ipv6 = 0; - sctp_init->nb_ipv4_addr = 1; -#if 0 - memcpy(&sctp_init->ipv4_address, - local_ip_addr, - sizeof(*local_ip_addr)); -#endif - sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address); - /* - * SR WARNING: ipv6 multi-homing fails sometimes for localhost. - * * * * Disable it for now. - */ - sctp_init->nb_ipv6_addr = 0; - sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1"; + char *addr_buf = (char *) (sctp_init + 1); + sctp_init->bind_address = addr_buf; + memcpy(addr_buf, local_ip_addr->ipv4_address, addr_len); return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message); } @@ -502,37 +489,22 @@ void MME_task_send_sctp_init_req(instance_t enb_id, m3ap_mme_sctp_req_t * m3ap_m // 2. use RC.rrc[enb_id] to fill the sctp_init_t with the ip, port // 3. creat an itti message to init - MessageDef *message_p = NULL; - - message_p = itti_alloc_new_message (TASK_M3AP_MME, 0, SCTP_INIT_MSG); -if(m3ap_mme_sctp_req==NULL) { - LOG_I(M3AP, "M3AP_SCTP_REQ(create socket)\n"); - message_p->ittiMsg.sctp_init.port = M3AP_PORT_NUMBER; - message_p->ittiMsg.sctp_init.ppid = M3AP_SCTP_PPID; - message_p->ittiMsg.sctp_init.ipv4 = 1; - message_p->ittiMsg.sctp_init.ipv6 = 0; - message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1; - //message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr); - message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr("127.0.0.8"); - -}else{ - - LOG_I(M3AP, "M3AP_SCTP_REQ(create socket) %s\n",m3ap_mme_sctp_req->mme_m3_ip_address.ipv4_address); - message_p->ittiMsg.sctp_init.port = m3ap_mme_sctp_req->mme_port_for_M3C; - message_p->ittiMsg.sctp_init.ppid = M3AP_SCTP_PPID; - message_p->ittiMsg.sctp_init.ipv4 = 1; - message_p->ittiMsg.sctp_init.ipv6 = 0; - message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1; - //message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr); - message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(m3ap_mme_sctp_req->mme_m3_ip_address.ipv4_address); - } - - /* - * SR WARNING: ipv6 multi-homing fails sometimes for localhost. - * * * * Disable it for now. - */ - message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0; - message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1"; + size_t addr_len = m3ap_mme_sctp_req != NULL ? strlen(m3ap_mme_sctp_req->mme_m3_ip_address.ipv4_address) + 1 : strlen("127.0.0.8") + 1; // the previous code might hardcode, support this + MessageDef *message_p = itti_alloc_new_message_sized(TASK_M3AP_MME, 0, SCTP_INIT_MSG, sizeof(sctp_init_t) + addr_len); + sctp_init_t *init = &SCTP_INIT_MSG(message_p); + char *addr_buf = (char *) (init + 1); // address after ITTI message end, allocated above + init->bind_address = addr_buf; + if (m3ap_mme_sctp_req == NULL) { + LOG_I(M3AP, "M3AP_SCTP_REQ(create socket)\n"); + init->port = M3AP_PORT_NUMBER; + init->ppid = M3AP_SCTP_PPID; + memcpy(addr_buf, "127.0.0.8", addr_len); + } else { + LOG_I(M3AP, "M3AP_SCTP_REQ(create socket) for %s %ld\n", m3ap_mme_sctp_req->mme_m3_ip_address.ipv4_address, addr_len); + init->port = m3ap_mme_sctp_req->mme_port_for_M3C; + init->ppid = M3AP_SCTP_PPID; + memcpy(addr_buf, m3ap_mme_sctp_req->mme_m3_ip_address.ipv4_address, addr_len); + } itti_send_msg_to_task(TASK_SCTP, enb_id, message_p); } diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index 84110ddda6..ffd4bba3f5 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -598,85 +598,44 @@ static int sctp_close_association(sctp_close_association_t *close_association_p) return 0; } -//------------------------------------------------------------------------------ -static int sctp_create_new_listener( - const instance_t instance, - const task_id_t requestor, - sctp_init_t *init_p, - int server_type) +static int sctp_create_new_listener(const instance_t instance, const task_id_t requestor, sctp_init_t *init_p, int server_type) { - struct sctp_event_subscribe event={0}; - struct sockaddr *addr = NULL; - struct sctp_cnx_list_elm_s *sctp_cnx = NULL; - uint16_t i = 0, j = 0; - int sd = 0; - int used_addresses = 0; + DevAssert(init_p != NULL); + DevAssert(init_p->bind_address != NULL); + int in_streams = 1; + int out_streams = 1; - DevAssert(init_p != NULL); + /* local address: IPv4 has priority, but can also handle IPv6 */ + const char *local = init_p->bind_address; - if (init_p->ipv4 == 0 && init_p->ipv6 == 0) { - SCTP_ERROR("Illegal IP configuration upper layer should request at" - "least ipv4 and/or ipv6 config\n"); - return -1; + struct addrinfo hints = {.ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM, .ai_protocol = IPPROTO_SCTP}; + struct addrinfo *serv; + + char port[12]; + snprintf(port, sizeof(port), "%d", init_p->port); + int status = getaddrinfo(local, port, &hints, &serv); + AssertFatal(status == 0, "getaddrinfo() failed: %s\n", gai_strerror(status)); + + int sd; + struct addrinfo *p = NULL; + for (p = serv; p != NULL; p = p->ai_next) { + char buf[512]; + const char *ip = print_ip(p, buf, sizeof(buf)); + SCTP_DEBUG("Trying %s for server socket creation\n", ip); + + /* SOCK_SEQPACKET to be able to reuse(?) socket through SCTP_INIT_MSG_MULTI_REQ */ + int socktype = server_type ? SOCK_SEQPACKET : SOCK_STREAM; + if ((sd = socket(serv->ai_family, socktype, serv->ai_protocol)) == -1) { + SCTP_WARN("Socket creation failed: %s\n", strerror(errno)); + continue; } - if ((used_addresses = init_p->nb_ipv4_addr + init_p->nb_ipv6_addr) == 0) { - SCTP_WARN("No address provided...\n"); - return -1; - } - - addr = calloc(used_addresses, sizeof(struct sockaddr)); - - SCTP_DEBUG("Creating new listen socket on port %u with\n", init_p->port); - - if (init_p->ipv4 == 1) { - struct sockaddr_in *ip4_addr; - - SCTP_DEBUG("ipv4 addresses:\n"); - - for (i = 0; i < init_p->nb_ipv4_addr; i++) { - SCTP_DEBUG("\t- "IPV4_ADDR"\n", IPV4_ADDR_FORMAT(init_p->ipv4_address[i])); - ip4_addr = (struct sockaddr_in *)&addr[i]; - ip4_addr->sin_family = AF_INET; - ip4_addr->sin_port = htons(init_p->port); - ip4_addr->sin_addr.s_addr = init_p->ipv4_address[i]; - } - } - - if (init_p->ipv6 == 1) { - struct sockaddr_in6 *ip6_addr; - - SCTP_DEBUG("ipv6 addresses:\n"); - - for (j = 0; j < init_p->nb_ipv6_addr; j++) { - SCTP_DEBUG("\t- %s\n", init_p->ipv6_address[j]); - ip6_addr = (struct sockaddr_in6 *)&addr[i + j]; - ip6_addr->sin6_family = AF_INET6; - ip6_addr->sin6_port = htons(init_p->port); - - if (inet_pton(AF_INET6, init_p->ipv6_address[j], - ip6_addr->sin6_addr.s6_addr) <= 0) { - SCTP_WARN("Provided ipv6 address %s is not valid\n", - init_p->ipv6_address[j]); - } - } - } - - if (server_type) { - if ((sd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0) { - SCTP_ERROR("socket: %s:%d\n", strerror(errno), errno); - free(addr); - return -1; - } - } - else { - if ((sd = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP)) < 0) { - SCTP_ERROR("socket: %s:%d\n", strerror(errno), errno); - free(addr); - return -1; - } - } + /* we assume we can set options, or something is likely broken; the + * connection won't operate properly */ + int ret = sctp_set_init_opt(sd, in_streams, out_streams, 0, 0); + AssertFatal(ret == 0, "sctp_set_init_opt() failed\n"); + struct sctp_event_subscribe event = {0}; event.sctp_data_io_event = 1; event.sctp_association_event = 1; event.sctp_address_event = 1; @@ -685,83 +644,55 @@ static int sctp_create_new_listener( event.sctp_shutdown_event = 1; event.sctp_partial_delivery_event = 1; - if (setsockopt(sd, IPPROTO_SCTP, SCTP_EVENTS, &event, - 8) < 0) { - SCTP_ERROR("setsockopt: %s:%d\n", strerror(errno), errno); - if (sd != -1) { - close(sd); - sd = -1; - } - free(addr); - return -1; - } + /* as above */ + ret = setsockopt(sd, serv->ai_protocol, SCTP_EVENTS, &event, 8); + AssertFatal(ret == 0, "setsockopt() IPPROTO_SCTP_EVENTS failed: %s\n", strerror(errno)); - sctp_cnx = calloc(1, sizeof(*sctp_cnx)); - - if (server_type) { - sctp_cnx->connection_type = SCTP_TYPE_MULTI_SERVER; - } - else { - sctp_cnx->connection_type = SCTP_TYPE_SERVER; - } - - sctp_cnx->sd = sd; - sctp_cnx->local_port = init_p->port; - sctp_cnx->in_streams = 32; - sctp_cnx->out_streams = 32; - sctp_cnx->ppid = init_p->ppid; - sctp_cnx->task_id = requestor; - sctp_cnx->instance = instance; - - /* Some pre-bind socket configuration */ - if (sctp_set_init_opt(sd, - sctp_cnx->in_streams, - sctp_cnx->out_streams, - 0, - 0) < 0) { - goto err; - } - - if (sctp_bindx(sd, addr, used_addresses, SCTP_BINDX_ADD_ADDR) != 0) { - SCTP_ERROR("sctp_bindx: %s:%d\n", strerror(errno), errno); - free(sctp_cnx); - sctp_cnx = NULL; - return -1; + /* if that fails, we will try the next address */ + ret = sctp_bindx(sd, p->ai_addr, 1, SCTP_BINDX_ADD_ADDR); + if (ret != 0) { + SCTP_WARN("sctp_bindx() SCTP_BINDX_ADD_ADDR failed: errno %d %s\n", errno, strerror(errno)); + close(sd); + continue; } if (listen(sd, 5) < 0) { - SCTP_ERROR("listen: %s:%d\n", strerror(errno), errno); - free(sctp_cnx); - sctp_cnx = NULL; - return -1; - } - SCTP_DEBUG("Created listen socket: %d\n", sd); - /* Insert new element at end of list */ - STAILQ_INSERT_TAIL(&sctp_cnx_list, sctp_cnx, entries); - sctp_nb_cnx++; - - /* Add the socket to list of fd monitored by ITTI */ - itti_subscribe_event_fd(TASK_SCTP, sd); - - return sd; -err: - - if (sd != -1) { - close(sd); - sd = -1; + SCTP_WARN("listen() failed: %s:%d\n", strerror(errno), errno); + close(sd); + return -1; } - if (sctp_cnx != NULL) { - free(sctp_cnx); - sctp_cnx = NULL; - } + SCTP_DEBUG("Created listen socket %d on %s:%s local %s\n", sd, ip, port, local); - if (addr != NULL) { - free(addr); - addr = NULL; - } + break; + } + freeaddrinfo(serv); + + if (p == NULL) { + SCTP_ERROR("could not open server socket, no SCTP listener active\n"); return -1; + } + + struct sctp_cnx_list_elm_s *sctp_cnx = calloc(1, sizeof(*sctp_cnx)); + AssertFatal(sctp_cnx != NULL, "out of memory\n"); + + sctp_cnx->connection_type = server_type ? SCTP_TYPE_MULTI_SERVER : SCTP_TYPE_SERVER; + sctp_cnx->sd = sd; + sctp_cnx->local_port = init_p->port; + sctp_cnx->in_streams = in_streams; + sctp_cnx->out_streams = out_streams; + sctp_cnx->ppid = init_p->ppid; + sctp_cnx->task_id = requestor; + sctp_cnx->instance = instance; + /* Insert new element at end of list */ + STAILQ_INSERT_TAIL(&sctp_cnx_list, sctp_cnx, entries); + sctp_nb_cnx++; + + /* Add the socket to list of fd monitored by ITTI */ + itti_subscribe_event_fd(TASK_SCTP, sd); + + return sd; } //------------------------------------------------------------------------------