/*---------------------------------------------------------------------------*/ int xio_on_connection_hello_req_recv(struct xio_connection *connection, struct xio_task *task) { xio_session_notify_new_connection(task->session, connection); xio_connection_send_hello_rsp(connection, task); connection->session->state = XIO_SESSION_STATE_ONLINE; connection->session->disable_teardown = 0; TRACE_LOG("session state is now ONLINE. session:%p\n", connection->session); xio_connection_set_state(connection, XIO_CONNECTION_STATE_ONLINE); return 0; }
/* first message after new connection are going trough the server */ static int xio_on_new_message(struct xio_server *server, struct xio_nexus *nexus, int event, union xio_nexus_event_data *event_data) { struct xio_session *session = NULL; struct xio_connection *connection = NULL; struct xio_connection *connection1 = NULL; struct xio_task *task; uint32_t tlv_type; struct xio_session_params params; int locked = 0; if (!server || !nexus || !event_data || !event_data->msg.task) { ERROR_LOG("server [new session]: failed " \ "invalid parameter\n"); return -1; } task = event_data->msg.task; params.type = XIO_SESSION_SERVER; params.initial_sn = 0; params.ses_ops = &server->ops; params.uri = server->uri; params.private_data = NULL; params.private_data_len = 0; params.user_context = server->cb_private_data; /* read the first message type */ tlv_type = xio_read_tlv_type(&event_data->msg.task->mbuf); if (tlv_type == XIO_SESSION_SETUP_REQ) { /* create new session */ session = xio_session_create(¶ms); if (!session) { ERROR_LOG("server [new session]: failed " \ " allocating session failed\n"); return -1; } DEBUG_LOG("server [new session]: server:%p, " \ "session:%p, nexus:%p ,session_id:%d\n", server, session, nexus, session->session_id); /* get transport class routines */ session->validators_cls = xio_nexus_get_validators_cls(nexus); connection = xio_session_alloc_connection(session, server->ctx, 0, server->cb_private_data); if (!connection) { ERROR_LOG("server failed to allocate new connection\n"); goto cleanup; } connection1 = xio_session_assign_nexus(session, nexus); if (!connection1) { ERROR_LOG("server failed to assign new connection\n"); goto cleanup1; } connection = connection1; xio_idr_add_uobj(usr_idr, session, "xio_session"); xio_idr_add_uobj(usr_idr, connection, "xio_connection"); xio_connection_set_state(connection, XIO_CONNECTION_STATE_ONLINE); xio_connection_keepalive_start(connection); task->session = session; task->connection = connection; } else if (tlv_type == XIO_CONNECTION_HELLO_REQ) { struct xio_session *session1; /* find the old session without lock */ session = xio_find_session(event_data->msg.task); if (!session) { ERROR_LOG("server [new connection]: failed " \ "session not found. server:%p\n", server); xio_nexus_close(nexus, NULL); return -1; } /* lock it and retry find */ mutex_lock(&session->lock); /* session before destruction - try to lock before continue */ session1 = xio_find_session(event_data->msg.task); if (!session1) { ERROR_LOG("server [new connection]: failed " \ "session not found. server:%p\n", server); xio_nexus_close(nexus, NULL); mutex_unlock(&session->lock); return -1; } locked = 1; task->session = session; DEBUG_LOG("server [new connection]: server:%p, " \ "session:%p, nexus:%p, session_id:%d\n", server, session, nexus, session->session_id); connection = xio_session_alloc_connection( task->session, server->ctx, 0, server->cb_private_data); if (!connection) { ERROR_LOG("server failed to allocate new connection\n"); goto cleanup; } connection1 = xio_session_assign_nexus(task->session, nexus); if (!connection1) { ERROR_LOG("server failed to assign new connection\n"); goto cleanup1; } connection = connection1; /* copy the server attributes to the connection */ xio_connection_set_ops(connection, &server->ops); task->connection = connection; /* This in a multiple-portal situation */ session->state = XIO_SESSION_STATE_ONLINE; xio_connection_set_state(connection, XIO_CONNECTION_STATE_ONLINE); xio_connection_keepalive_start(connection); xio_idr_add_uobj(usr_idr, connection, "xio_connection"); } else { ERROR_LOG("server unexpected message\n"); return -1; } /* route the message to the session */ if (session) xio_nexus_notify_observer(nexus, &session->observer, event, event_data); if (locked) mutex_unlock(&session->lock); return 0; cleanup1: if (connection) xio_session_free_connection(connection); cleanup: if (session) xio_session_destroy(session); return -1; }