- Mark SCTP sockets as non-blocking to avoid locks in SCTP layer, particularly at connection
- Fixed some log points formats git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4398 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -355,7 +355,7 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id,
|
|||||||
if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance,
|
if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance,
|
||||||
initialContextSetupRequest_p->eNB_UE_S1AP_ID)) == NULL) {
|
initialContextSetupRequest_p->eNB_UE_S1AP_ID)) == NULL) {
|
||||||
S1AP_ERROR("[SCTP %d] Received initial context setup request for non "
|
S1AP_ERROR("[SCTP %d] Received initial context setup request for non "
|
||||||
"existing UE context %06x\n", assoc_id,
|
"existing UE context 0x%06x\n", assoc_id,
|
||||||
initialContextSetupRequest_p->eNB_UE_S1AP_ID);
|
initialContextSetupRequest_p->eNB_UE_S1AP_ID);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
|
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
|
||||||
S1AP_ERROR("[SCTP %d] Received initial context setup request for non "
|
S1AP_ERROR("[SCTP %d] Received NAS downlink message for non "
|
||||||
"existing MME context\n", assoc_id);
|
"existing MME context\n", assoc_id);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -217,8 +217,9 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id,
|
|||||||
if ((ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance,
|
if ((ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance,
|
||||||
downlink_NAS_transport_p->eNB_UE_S1AP_ID)) == NULL)
|
downlink_NAS_transport_p->eNB_UE_S1AP_ID)) == NULL)
|
||||||
{
|
{
|
||||||
S1AP_ERROR("[SCTP %d] Received initial context setup request for non "
|
S1AP_ERROR("[SCTP %d] Received NAS downlink message for non "
|
||||||
"existing UE context\n", assoc_id);
|
"existing UE context: %06x\n", assoc_id,
|
||||||
|
downlink_NAS_transport_p->eNB_UE_S1AP_ID);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +231,7 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id,
|
|||||||
} else {
|
} else {
|
||||||
/* We already have a mme ue s1ap id check the received is the same */
|
/* We already have a mme ue s1ap id check the received is the same */
|
||||||
if (ue_desc_p->mme_ue_s1ap_id != downlink_NAS_transport_p->mme_ue_s1ap_id) {
|
if (ue_desc_p->mme_ue_s1ap_id != downlink_NAS_transport_p->mme_ue_s1ap_id) {
|
||||||
S1AP_ERROR("[SCTP %d] Mismatch is MME UE S1AP ID (0x%08x != 0x%08x)\n",
|
S1AP_ERROR("[SCTP %d] Mismatch in MME UE S1AP ID (0x%08x != 0x%08x)\n",
|
||||||
downlink_NAS_transport_p->mme_ue_s1ap_id,
|
downlink_NAS_transport_p->mme_ue_s1ap_id,
|
||||||
ue_desc_p->mme_ue_s1ap_id,
|
ue_desc_p->mme_ue_s1ap_id,
|
||||||
assoc_id);
|
assoc_id);
|
||||||
@@ -265,7 +266,7 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_
|
|||||||
if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, s1ap_uplink_nas_p->eNB_ue_s1ap_id)) == NULL)
|
if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, s1ap_uplink_nas_p->eNB_ue_s1ap_id)) == NULL)
|
||||||
{
|
{
|
||||||
/* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
|
/* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
|
||||||
S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %u\n",
|
S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %06x\n",
|
||||||
s1ap_uplink_nas_p->eNB_ue_s1ap_id);
|
s1ap_uplink_nas_p->eNB_ue_s1ap_id);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -342,7 +343,7 @@ int s1ap_eNB_initial_ctxt_resp(
|
|||||||
initial_ctxt_resp_p->eNB_ue_s1ap_id)) == NULL)
|
initial_ctxt_resp_p->eNB_ue_s1ap_id)) == NULL)
|
||||||
{
|
{
|
||||||
/* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
|
/* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
|
||||||
S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %u\n",
|
S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n",
|
||||||
initial_ctxt_resp_p->eNB_ue_s1ap_id);
|
initial_ctxt_resp_p->eNB_ue_s1ap_id);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -354,7 +355,7 @@ int s1ap_eNB_initial_ctxt_resp(
|
|||||||
ue_context_p->ue_state == S1AP_UE_WAITING_CSR))
|
ue_context_p->ue_state == S1AP_UE_WAITING_CSR))
|
||||||
{
|
{
|
||||||
S1AP_WARN("You are attempting to send NAS data over non-connected "
|
S1AP_WARN("You are attempting to send NAS data over non-connected "
|
||||||
"eNB ue s1ap id: %u, current state: %d\n",
|
"eNB ue s1ap id: %06x, current state: %d\n",
|
||||||
initial_ctxt_resp_p->eNB_ue_s1ap_id, ue_context_p->ue_state);
|
initial_ctxt_resp_p->eNB_ue_s1ap_id, ue_context_p->ue_state);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,3 +24,24 @@ int sctp_itti_send_new_message_ind(task_id_t task_id, uint32_t assoc_id, uint8_t
|
|||||||
|
|
||||||
return itti_send_msg_to_task(task_id, INSTANCE_DEFAULT, message_p);
|
return itti_send_msg_to_task(task_id, INSTANCE_DEFAULT, message_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sctp_itti_send_association_resp(task_id_t task_id, instance_t instance,
|
||||||
|
int32_t assoc_id,
|
||||||
|
uint16_t cnx_id, enum sctp_state_e state,
|
||||||
|
uint16_t out_streams, uint16_t in_streams)
|
||||||
|
{
|
||||||
|
MessageDef *message_p;
|
||||||
|
sctp_new_association_resp_t *sctp_new_association_resp_p;
|
||||||
|
|
||||||
|
message_p = itti_alloc_new_message(TASK_SCTP, SCTP_NEW_ASSOCIATION_RESP);
|
||||||
|
|
||||||
|
sctp_new_association_resp_p = &message_p->msg.sctp_new_association_resp;
|
||||||
|
|
||||||
|
sctp_new_association_resp_p->in_streams = in_streams;
|
||||||
|
sctp_new_association_resp_p->out_streams = out_streams;
|
||||||
|
sctp_new_association_resp_p->sctp_state = state;
|
||||||
|
sctp_new_association_resp_p->assoc_id = assoc_id;
|
||||||
|
sctp_new_association_resp_p->ulp_cnx_id = cnx_id;
|
||||||
|
|
||||||
|
return itti_send_msg_to_task(task_id, instance, message_p);
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,4 +4,9 @@
|
|||||||
int sctp_itti_send_new_message_ind(task_id_t task_id, uint32_t assoc_id, uint8_t *buffer,
|
int sctp_itti_send_new_message_ind(task_id_t task_id, uint32_t assoc_id, uint8_t *buffer,
|
||||||
uint32_t buffer_length, uint16_t stream);
|
uint32_t buffer_length, uint16_t stream);
|
||||||
|
|
||||||
|
int sctp_itti_send_association_resp(task_id_t task_id, instance_t instance,
|
||||||
|
int32_t assoc_id,
|
||||||
|
uint16_t cnx_id, enum sctp_state_e state,
|
||||||
|
uint16_t out_streams, uint16_t in_streams);
|
||||||
|
|
||||||
#endif /* SCTP_ITTI_MESSAGING_H_ */
|
#endif /* SCTP_ITTI_MESSAGING_H_ */
|
||||||
|
|||||||
@@ -112,6 +112,8 @@ void sctp_handle_new_association_req(
|
|||||||
struct sctp_initmsg init;
|
struct sctp_initmsg init;
|
||||||
struct sctp_event_subscribe events;
|
struct sctp_event_subscribe events;
|
||||||
|
|
||||||
|
struct sctp_cnx_list_elm_s *sctp_cnx = NULL;
|
||||||
|
|
||||||
/* Prepare a new SCTP association as requested by upper layer and try to connect
|
/* Prepare a new SCTP association as requested by upper layer and try to connect
|
||||||
* to remote host.
|
* to remote host.
|
||||||
*/
|
*/
|
||||||
@@ -138,6 +140,7 @@ void sctp_handle_new_association_req(
|
|||||||
&init, (socklen_t)sizeof(struct sctp_initmsg)) < 0) {
|
&init, (socklen_t)sizeof(struct sctp_initmsg)) < 0) {
|
||||||
SCTP_ERROR("Setsockopt IPPROTO_SCTP_INITMSG failed: %s\n",
|
SCTP_ERROR("Setsockopt IPPROTO_SCTP_INITMSG failed: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
close(sd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,6 +150,15 @@ void sctp_handle_new_association_req(
|
|||||||
sizeof(struct sctp_event_subscribe)) < 0) {
|
sizeof(struct sctp_event_subscribe)) < 0) {
|
||||||
SCTP_ERROR("Setsockopt IPPROTO_SCTP_EVENTS failed: %s\n",
|
SCTP_ERROR("Setsockopt IPPROTO_SCTP_EVENTS failed: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
close(sd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark the socket as non-blocking */
|
||||||
|
if (fcntl(sd, F_SETFL, O_NONBLOCK) < 0) {
|
||||||
|
SCTP_ERROR("fcntl F_SETFL O_NONBLOCK failed: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
close(sd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,6 +181,7 @@ void sctp_handle_new_association_req(
|
|||||||
SCTP_ERROR("Failed to convert ipv6 address %*s to network type\n",
|
SCTP_ERROR("Failed to convert ipv6 address %*s to network type\n",
|
||||||
strlen(sctp_new_association_req_p->remote_address.ipv6_address),
|
strlen(sctp_new_association_req_p->remote_address.ipv6_address),
|
||||||
sctp_new_association_req_p->remote_address.ipv6_address);
|
sctp_new_association_req_p->remote_address.ipv6_address);
|
||||||
|
close(sd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,6 +200,7 @@ void sctp_handle_new_association_req(
|
|||||||
SCTP_ERROR("Failed to convert ipv4 address %*s to network type\n",
|
SCTP_ERROR("Failed to convert ipv4 address %*s to network type\n",
|
||||||
strlen(sctp_new_association_req_p->remote_address.ipv4_address),
|
strlen(sctp_new_association_req_p->remote_address.ipv4_address),
|
||||||
sctp_new_association_req_p->remote_address.ipv4_address);
|
sctp_new_association_req_p->remote_address.ipv4_address);
|
||||||
|
close(sd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,58 +216,34 @@ void sctp_handle_new_association_req(
|
|||||||
SCTP_DEBUG("Connecting...\n");
|
SCTP_DEBUG("Connecting...\n");
|
||||||
|
|
||||||
/* Connect to remote host and port */
|
/* Connect to remote host and port */
|
||||||
if (sctp_connectx(sd, (struct sockaddr *)addr, used_address, &assoc_id) < 0) {
|
if (sctp_connectx(sd, (struct sockaddr *)addr, used_address, &assoc_id) < 0)
|
||||||
SCTP_ERROR("Connect failed: %s\n", strerror(errno));
|
{
|
||||||
return;
|
/* sctp_connectx on non-blocking socket return EINPROGRESS */
|
||||||
|
if (errno != EINPROGRESS) {
|
||||||
|
SCTP_ERROR("Connect failed: %s\n", strerror(errno));
|
||||||
|
sctp_itti_send_association_resp(
|
||||||
|
requestor, instance, -1, sctp_new_association_req_p->ulp_cnx_id,
|
||||||
|
SCTP_STATE_UNREACHABLE, 0, 0);
|
||||||
|
close(sd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SCTP_DEBUG("Connected... assoc_id %u\n", assoc_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sctp_get_peeraddresses(sd, NULL, NULL) != 0) {
|
sctp_cnx = calloc(1, sizeof(*sctp_cnx));
|
||||||
/* TODO Failure -> notify upper layer */
|
|
||||||
|
|
||||||
} else {
|
|
||||||
MessageDef *new_message_p;
|
|
||||||
sctp_new_association_resp_t *sctp_new_association_resp;
|
|
||||||
struct sctp_cnx_list_elm_s *sctp_cnx = NULL;
|
|
||||||
|
|
||||||
sctp_cnx = calloc(1, sizeof(*sctp_cnx));
|
sctp_cnx->sd = sd;
|
||||||
|
sctp_cnx->task_id = requestor;
|
||||||
|
sctp_cnx->cnx_id = sctp_new_association_req_p->ulp_cnx_id;
|
||||||
|
sctp_cnx->ppid = sctp_new_association_req_p->ppid;
|
||||||
|
sctp_cnx->instance = instance;
|
||||||
|
|
||||||
sctp_cnx->sd = sd;
|
/* Insert new element at end of list */
|
||||||
sctp_cnx->task_id = requestor;
|
STAILQ_INSERT_TAIL(&sctp_cnx_list, sctp_cnx, entries);
|
||||||
sctp_cnx->cnx_id = sctp_new_association_req_p->ulp_cnx_id;
|
sctp_nb_cnx++;
|
||||||
sctp_cnx->ppid = sctp_new_association_req_p->ppid;
|
|
||||||
sctp_cnx->instance = instance;
|
|
||||||
|
|
||||||
/* Get socket info */
|
SCTP_DEBUG("Inserted new descriptor for sd %d in list, nb elements %u, assoc_id %d\n",
|
||||||
sctp_get_sockinfo(sd,
|
sd, sctp_nb_cnx, assoc_id);
|
||||||
&sctp_cnx->in_streams,
|
|
||||||
&sctp_cnx->out_streams,
|
|
||||||
&sctp_cnx->assoc_id);
|
|
||||||
|
|
||||||
/* Insert new element at end of list */
|
|
||||||
STAILQ_INSERT_TAIL(&sctp_cnx_list, sctp_cnx, entries);
|
|
||||||
sctp_nb_cnx++;
|
|
||||||
|
|
||||||
SCTP_DEBUG("Inserted new descriptor for sd %d in list, nb elements %u, assoc_id %d\n",
|
|
||||||
sd, sctp_nb_cnx, assoc_id);
|
|
||||||
|
|
||||||
new_message_p = itti_alloc_new_message(TASK_SCTP, SCTP_NEW_ASSOCIATION_RESP);
|
|
||||||
|
|
||||||
sctp_new_association_resp = &new_message_p->msg.sctp_new_association_resp;
|
|
||||||
|
|
||||||
sctp_new_association_resp->in_streams = sctp_cnx->in_streams;
|
|
||||||
sctp_new_association_resp->out_streams = sctp_cnx->out_streams;
|
|
||||||
sctp_new_association_resp->sctp_state = SCTP_STATE_ESTABLISHED;
|
|
||||||
sctp_new_association_resp->ulp_cnx_id = sctp_new_association_req_p->ulp_cnx_id;
|
|
||||||
sctp_new_association_resp->assoc_id = sctp_cnx->assoc_id;
|
|
||||||
|
|
||||||
SCTP_DEBUG("Sending SCTP new association resp message to %s\n",
|
|
||||||
itti_get_task_name(requestor));
|
|
||||||
|
|
||||||
itti_send_msg_to_task(requestor, sctp_cnx->instance, new_message_p);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sctp_send_data(instance_t instance, task_id_t task_id, sctp_data_req_t *sctp_data_req_p)
|
void sctp_send_data(instance_t instance, task_id_t task_id, sctp_data_req_t *sctp_data_req_p)
|
||||||
@@ -321,6 +311,9 @@ inline void sctp_eNB_read_from_socket(struct sctp_cnx_list_elm_s *sctp_cnx)
|
|||||||
union sctp_notification *snp;
|
union sctp_notification *snp;
|
||||||
snp = (union sctp_notification *)buffer;
|
snp = (union sctp_notification *)buffer;
|
||||||
|
|
||||||
|
SCTP_DEBUG("Received notification for sd %d, type %u\n",
|
||||||
|
sctp_cnx->sd, snp->sn_header.sn_type);
|
||||||
|
|
||||||
/* Client deconnection */
|
/* Client deconnection */
|
||||||
if (SCTP_SHUTDOWN_EVENT == snp->sn_header.sn_type) {
|
if (SCTP_SHUTDOWN_EVENT == snp->sn_header.sn_type) {
|
||||||
DevMessage("Other peer has requested a com down -> not handled\n");
|
DevMessage("Other peer has requested a com down -> not handled\n");
|
||||||
@@ -337,34 +330,22 @@ inline void sctp_eNB_read_from_socket(struct sctp_cnx_list_elm_s *sctp_cnx)
|
|||||||
/* New physical association requested by a peer */
|
/* New physical association requested by a peer */
|
||||||
switch (sctp_assoc_changed->sac_state) {
|
switch (sctp_assoc_changed->sac_state) {
|
||||||
case SCTP_COMM_UP: {
|
case SCTP_COMM_UP: {
|
||||||
// struct sctp_association_s *new_association;
|
if (sctp_get_peeraddresses(sctp_cnx->sd, NULL, NULL) != 0)
|
||||||
//
|
{
|
||||||
// sctp_get_sockinfo(sd, NULL, NULL, NULL);
|
/* TODO Failure -> notify upper layer */
|
||||||
//
|
} else {
|
||||||
// SCTP_DEBUG("New connection\n");
|
sctp_get_sockinfo(sctp_cnx->sd, &sctp_cnx->in_streams,
|
||||||
// if ((new_association = sctp_add_new_peer()) == NULL) {
|
&sctp_cnx->out_streams, &sctp_cnx->assoc_id);
|
||||||
// // TODO: handle this case
|
}
|
||||||
// DevMessage("Unexpected error...\n");
|
|
||||||
// return SCTP_RC_ERROR;
|
SCTP_DEBUG("Comm up notified for sd %d, assigned assoc_id %d\n",
|
||||||
// } else {
|
sctp_cnx->sd, sctp_cnx->assoc_id);
|
||||||
// new_association->sd = sd;
|
|
||||||
// new_association->ppid = ppid;
|
sctp_itti_send_association_resp(
|
||||||
// new_association->instreams = sctp_assoc_changed->sac_inbound_streams;
|
sctp_cnx->task_id, sctp_cnx->instance, sctp_cnx->assoc_id,
|
||||||
// new_association->outstreams = sctp_assoc_changed->sac_outbound_streams;
|
sctp_cnx->cnx_id, SCTP_STATE_ESTABLISHED,
|
||||||
// new_association->assoc_id = sctp_assoc_changed->sac_assoc_id;
|
sctp_cnx->out_streams, sctp_cnx->in_streams);
|
||||||
//
|
|
||||||
// sctp_get_localaddresses(sd, NULL, NULL);
|
|
||||||
// sctp_get_peeraddresses(sd, &new_association->peer_addresses,
|
|
||||||
// &new_association->nb_peer_addresses);
|
|
||||||
//
|
|
||||||
// if (sctp_itti_send_new_association(
|
|
||||||
// new_association->assoc_id, new_association->instreams,
|
|
||||||
// new_association->outstreams) < 0)
|
|
||||||
// {
|
|
||||||
// SCTP_ERROR("Failed to send message to S1AP\n");
|
|
||||||
// return SCTP_RC_ERROR;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user