diff options
author | Florin Coras <fcoras@cisco.com> | 2019-10-21 16:07:46 -0700 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2020-04-03 22:10:22 +0000 |
commit | 00e01d3e875bb18397ff81e0f58f9b468477f473 (patch) | |
tree | 277b9ce692a465644de5d3481b42e6cce6394f46 | |
parent | 39aa7a5202a6a875bd6f5d341cb07f19ab0bf51e (diff) |
session: improve error reporting
Type: improvement
Change-Id: I9dd850a1ce85b0adb5136233f176117e0ee38817
Signed-off-by: Florin Coras <fcoras@cisco.com>
31 files changed, 199 insertions, 160 deletions
diff --git a/src/plugins/hs_apps/echo_client.c b/src/plugins/hs_apps/echo_client.c index 551e46b987e..3c55c6dc720 100644 --- a/src/plugins/hs_apps/echo_client.c +++ b/src/plugins/hs_apps/echo_client.c @@ -362,7 +362,8 @@ echo_clients_init (vlib_main_t * vm) static int quic_echo_clients_qsession_connected_callback (u32 app_index, u32 api_context, - session_t * s, u8 is_fail) + session_t * s, + session_error_t err) { echo_client_main_t *ecm = &echo_client_main; vnet_connect_args_t *a = 0; @@ -406,7 +407,8 @@ quic_echo_clients_qsession_connected_callback (u32 app_index, u32 api_context, static int quic_echo_clients_session_connected_callback (u32 app_index, u32 api_context, - session_t * s, u8 is_fail) + session_t * s, + session_error_t err) { echo_client_main_t *ecm = &echo_client_main; eclient_session_t *session; @@ -416,7 +418,7 @@ quic_echo_clients_session_connected_callback (u32 app_index, u32 api_context, if (PREDICT_FALSE (ecm->run_test != ECHO_CLIENTS_STARTING)) return -1; - if (is_fail) + if (err) { clib_warning ("connection %d failed!", api_context); ecm->run_test = ECHO_CLIENTS_EXITING; @@ -427,7 +429,7 @@ quic_echo_clients_session_connected_callback (u32 app_index, u32 api_context, if (s->listener_handle == SESSION_INVALID_HANDLE) return quic_echo_clients_qsession_connected_callback (app_index, api_context, s, - is_fail); + err); DBG ("STREAM Connection callback %d", api_context); thread_index = s->thread_index; @@ -479,7 +481,7 @@ quic_echo_clients_session_connected_callback (u32 app_index, u32 api_context, static int echo_clients_session_connected_callback (u32 app_index, u32 api_context, - session_t * s, u8 is_fail) + session_t * s, session_error_t err) { echo_client_main_t *ecm = &echo_client_main; eclient_session_t *session; @@ -489,7 +491,7 @@ echo_clients_session_connected_callback (u32 app_index, u32 api_context, if (PREDICT_FALSE (ecm->run_test != ECHO_CLIENTS_STARTING)) return -1; - if (is_fail) + if (err) { clib_warning ("connection %d failed!", api_context); ecm->run_test = ECHO_CLIENTS_EXITING; diff --git a/src/plugins/hs_apps/echo_server.c b/src/plugins/hs_apps/echo_server.c index 362d278119c..c8335e3d813 100644 --- a/src/plugins/hs_apps/echo_server.c +++ b/src/plugins/hs_apps/echo_server.c @@ -125,7 +125,7 @@ echo_server_session_reset_callback (session_t * s) int echo_server_session_connected_callback (u32 app_index, u32 api_context, - session_t * s, u8 is_fail) + session_t * s, session_error_t err) { clib_warning ("called..."); return -1; diff --git a/src/plugins/hs_apps/http_server.c b/src/plugins/hs_apps/http_server.c index cc998a6f661..ab3bab15b10 100644 --- a/src/plugins/hs_apps/http_server.c +++ b/src/plugins/hs_apps/http_server.c @@ -690,7 +690,7 @@ http_server_session_reset_callback (session_t * s) static int http_server_session_connected_callback (u32 app_index, u32 api_context, - session_t * s, u8 is_fail) + session_t * s, session_error_t err) { clib_warning ("called..."); return -1; diff --git a/src/plugins/hs_apps/proxy.c b/src/plugins/hs_apps/proxy.c index ca46aef2ae0..83b26222adb 100644 --- a/src/plugins/hs_apps/proxy.c +++ b/src/plugins/hs_apps/proxy.c @@ -211,7 +211,7 @@ proxy_reset_callback (session_t * s) static int proxy_connected_callback (u32 app_index, u32 api_context, - session_t * s, u8 is_fail) + session_t * s, session_error_t err) { clib_warning ("called..."); return -1; @@ -363,13 +363,13 @@ static session_cb_vft_t proxy_session_cb_vft = { static int active_open_connected_callback (u32 app_index, u32 opaque, - session_t * s, u8 is_fail) + session_t * s, session_error_t err) { proxy_main_t *pm = &proxy_main; proxy_session_t *ps; u8 thread_index = vlib_get_thread_index (); - if (is_fail) + if (err) { clib_warning ("connection %d failed!", opaque); return 0; diff --git a/src/plugins/http_static/static_server.c b/src/plugins/http_static/static_server.c index 888cf416e80..8945ee35036 100644 --- a/src/plugins/http_static/static_server.c +++ b/src/plugins/http_static/static_server.c @@ -1118,7 +1118,8 @@ http_static_server_session_reset_callback (session_t * s) static int http_static_server_session_connected_callback (u32 app_index, u32 api_context, - session_t * s, u8 is_fail) + session_t * s, + session_error_t err) { clib_warning ("called..."); return -1; diff --git a/src/plugins/quic/quic.c b/src/plugins/quic/quic.c index 14002a253d7..4d809446130 100644 --- a/src/plugins/quic/quic.c +++ b/src/plugins/quic/quic.c @@ -1258,18 +1258,19 @@ quic_connect_stream (session_t * quic_session, session_endpoint_cfg_t * sep) stream_session->session_state = SESSION_STATE_READY; /* For now we only reset streams. Cleanup will be triggered by timers */ - if (app_worker_init_connected (app_wrk, stream_session)) + if ((rv = app_worker_init_connected (app_wrk, stream_session))) { QUIC_ERR ("failed to app_worker_init_connected"); quicly_reset_stream (stream, QUIC_APP_CONNECT_NOTIFY_ERROR); - return app_worker_connect_notify (app_wrk, NULL, sep->opaque); + return app_worker_connect_notify (app_wrk, NULL, rv, sep->opaque); } svm_fifo_add_want_deq_ntf (stream_session->rx_fifo, SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL | SVM_FIFO_WANT_DEQ_NOTIF_IF_EMPTY); - if (app_worker_connect_notify (app_wrk, stream_session, sep->opaque)) + if (app_worker_connect_notify (app_wrk, stream_session, SESSION_E_NONE, + sep->opaque)) { QUIC_ERR ("failed to notify app"); quic_increment_counter (QUIC_ERROR_CLOSED_STREAM, 1); @@ -1612,17 +1613,17 @@ quic_on_quic_session_connected (quic_ctx_t * ctx) /* If quic session connected fails, immediatly close connection */ app_wrk = app_worker_get (ctx->parent_app_wrk_id); - if (app_worker_init_connected (app_wrk, quic_session)) + if ((rv = app_worker_init_connected (app_wrk, quic_session))) { QUIC_ERR ("failed to app_worker_init_connected"); quic_proto_on_close (ctx_id, thread_index); - app_worker_connect_notify (app_wrk, NULL, ctx->client_opaque); + app_worker_connect_notify (app_wrk, NULL, rv, ctx->client_opaque); return; } quic_session->session_state = SESSION_STATE_CONNECTING; if ((rv = app_worker_connect_notify (app_wrk, quic_session, - ctx->client_opaque))) + SESSION_E_NONE, ctx->client_opaque))) { QUIC_ERR ("failed to notify app %d", rv); quic_proto_on_close (ctx_id, thread_index); @@ -1739,7 +1740,8 @@ quic_transfer_connection (u32 ctx_index, u32 dest_thread) static int quic_udp_session_connected_callback (u32 quic_app_index, u32 ctx_index, - session_t * udp_session, u8 is_fail) + session_t * udp_session, + session_error_t err) { QUIC_DBG (2, "QSession is now connected (id %u)", udp_session->session_index); @@ -1759,14 +1761,14 @@ quic_udp_session_connected_callback (u32 quic_app_index, u32 ctx_index, ctx = quic_ctx_get (ctx_index, thread_index); - if (is_fail) + if (err) { u32 api_context; app_wrk = app_worker_get_if_valid (ctx->parent_app_wrk_id); if (app_wrk) { api_context = ctx->c_s_index; - app_worker_connect_notify (app_wrk, 0, api_context); + app_worker_connect_notify (app_wrk, 0, SESSION_E_NONE, api_context); } return 0; } diff --git a/src/plugins/tlsmbedtls/tls_mbedtls.c b/src/plugins/tlsmbedtls/tls_mbedtls.c index dafb0900805..7b722faf822 100644 --- a/src/plugins/tlsmbedtls/tls_mbedtls.c +++ b/src/plugins/tlsmbedtls/tls_mbedtls.c @@ -414,11 +414,11 @@ mbedtls_ctx_handshake_rx (tls_ctx_t * ctx) */ if (ctx->srv_hostname) { - tls_notify_app_connected (ctx, /* is failed */ 0); + tls_notify_app_connected (ctx, SESSION_E_TLS_HANDSHAKE); return -1; } } - tls_notify_app_connected (ctx, /* is failed */ 0); + tls_notify_app_connected (ctx, SESSION_E_NONE); } else { diff --git a/src/plugins/tlsopenssl/tls_openssl.c b/src/plugins/tlsopenssl/tls_openssl.c index 6d0364c3acb..43bb13ff967 100644 --- a/src/plugins/tlsopenssl/tls_openssl.c +++ b/src/plugins/tlsopenssl/tls_openssl.c @@ -317,7 +317,7 @@ openssl_handle_handshake_failure (tls_ctx_t * ctx) /* * Also handles cleanup of the pre-allocated session */ - tls_notify_app_connected (ctx, /* is failed */ 1); + tls_notify_app_connected (ctx, SESSION_E_TLS_HANDSHAKE); } } @@ -385,11 +385,11 @@ openssl_ctx_handshake_rx (tls_ctx_t * ctx, session_t * tls_session) */ if (ctx->srv_hostname) { - tls_notify_app_connected (ctx, /* is failed */ 0); + tls_notify_app_connected (ctx, SESSION_E_TLS_HANDSHAKE); return -1; } } - tls_notify_app_connected (ctx, /* is failed */ 0); + tls_notify_app_connected (ctx, SESSION_E_NONE); } else { diff --git a/src/plugins/unittest/segment_manager_test.c b/src/plugins/unittest/segment_manager_test.c index 8f362f40cb6..4992e2e1670 100644 --- a/src/plugins/unittest/segment_manager_test.c +++ b/src/plugins/unittest/segment_manager_test.c @@ -39,7 +39,7 @@ dummy_session_reset_callback (session_t * s) static int dummy_session_connected_callback (u32 app_index, u32 api_context, - session_t * s, u8 is_fail) + session_t * s, session_error_t err) { clib_warning ("called..."); return 0; diff --git a/src/plugins/unittest/session_test.c b/src/plugins/unittest/session_test.c index 8d5566feb46..9368f9f80f7 100644 --- a/src/plugins/unittest/session_test.c +++ b/src/plugins/unittest/session_test.c @@ -54,7 +54,7 @@ volatile u32 connected_session_index = ~0; volatile u32 connected_session_thread = ~0; int dummy_session_connected_callback (u32 app_index, u32 api_context, - session_t * s, u8 is_fail) + session_t * s, session_error_t err) { if (s) { @@ -596,7 +596,7 @@ session_test_namespace (vlib_main_t * vm, unformat_input_t * input) connect_args.app_index = client_index; error = vnet_connect (&connect_args); SESSION_TEST ((error != 0), "client connect should return error code"); - SESSION_TEST ((error == VNET_API_ERROR_INVALID_VALUE), + SESSION_TEST ((error == SESSION_E_INVALID_RMT_IP), "error code should be invalid value (zero ip)"); SESSION_TEST ((dummy_segment_count == 0), "shouldn't have received request to map new segment"); @@ -678,8 +678,8 @@ session_test_namespace (vlib_main_t * vm, unformat_input_t * input) vnet_application_attach (&attach_args); error = vnet_connect (&connect_args); SESSION_TEST ((error != 0), "client connect should return error code"); - SESSION_TEST ((error == VNET_API_ERROR_SESSION_CONNECT), - "error code should be connect (not in same ns)"); + SESSION_TEST ((error == SESSION_E_NOROUTE), + "error code should be noroute (not in same ns)"); detach_args.app_index = client_index; vnet_application_detach (&detach_args); @@ -1255,8 +1255,7 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input) /* Try connecting */ error = vnet_connect (&connect_args); SESSION_TEST ((error != 0), "connect should fail"); - SESSION_TEST ((error == VNET_API_ERROR_APP_CONNECT_FILTERED), - "connect should be filtered"); + SESSION_TEST ((error == SESSION_E_FILTERED), "connect should be filtered"); sep.ip.ip4.as_u32 -= 1 << 24; @@ -1529,8 +1528,7 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input) error = vnet_connect (&connect_args); SESSION_TEST ((error != 0), "connect should fail"); - SESSION_TEST ((error == VNET_API_ERROR_APP_CONNECT_FILTERED), - "connect should be filtered"); + SESSION_TEST ((error == SESSION_E_FILTERED), "connect should be filtered"); /* * Lookup test namespace @@ -1542,8 +1540,7 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input) connect_args.app_index = server_index; error = vnet_connect (&connect_args); SESSION_TEST ((error != 0), "connect should fail"); - SESSION_TEST ((error == VNET_API_ERROR_APP_CONNECT_FILTERED), - "connect should be filtered"); + SESSION_TEST ((error == SESSION_E_FILTERED), "connect should be filtered"); args.table_args.is_add = 0; vnet_session_rule_add_del (&args); diff --git a/src/vcl/vcl_bapi.c b/src/vcl/vcl_bapi.c index 077024ed2cf..4ec09089cd8 100644 --- a/src/vcl/vcl_bapi.c +++ b/src/vcl/vcl_bapi.c @@ -33,7 +33,7 @@ #include <vpp/api/vpe_all_api_h.h> #undef vl_printfun -u8 * +static u8 * format_api_error (u8 * s, va_list * args) { i32 error = va_arg (*args, u32); diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h index 38818d2d356..12af09fbf55 100644 --- a/src/vcl/vcl_private.h +++ b/src/vcl/vcl_private.h @@ -667,8 +667,6 @@ void vcl_segment_detach (u64 segment_handle); u32 vcl_max_nsid_len (void); -u8 *format_api_error (u8 * s, va_list * args); - void vls_init (); #endif /* SRC_VCL_VCL_PRIVATE_H_ */ diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index ba1f1166556..9a19348cad4 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -445,7 +445,7 @@ vcl_session_connected_handler (vcl_worker_t * wrk, if (mp->retval) { VDBG (0, "ERROR: session index %u: connect failed! %U", - session_index, format_api_error, ntohl (mp->retval)); + session_index, format_session_error, mp->retval); session->session_state = STATE_DETACHED | STATE_DISCONNECT; session->vpp_handle = mp->handle; return session_index; @@ -565,7 +565,7 @@ vcl_session_bound_handler (vcl_worker_t * wrk, session_bound_msg_t * mp) if (mp->retval) { VERR ("session %u [0x%llx]: bind failed: %U", sid, mp->handle, - format_api_error, mp->retval); + format_session_error, mp->retval); if (session) { session->session_state = STATE_DETACHED; @@ -633,7 +633,7 @@ vcl_session_unlisten_reply_handler (vcl_worker_t * wrk, void *data) if (mp->retval) VDBG (0, "ERROR: session %u [0xllx]: unlisten failed: %U", - s->session_index, mp->handle, format_api_error, ntohl (mp->retval)); + s->session_index, mp->handle, format_session_error, mp->retval); if (mp->context != wrk->wrk_index) VDBG (0, "wrong context"); diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c index 7923d2d050e..8d7c909ba67 100644 --- a/src/vnet/session/application.c +++ b/src/vnet/session/application.c @@ -1019,7 +1019,7 @@ vnet_connect (vnet_connect_args_t * a) ASSERT (vlib_thread_is_main_w_barrier ()); if (session_endpoint_is_zero (&a->sep)) - return VNET_API_ERROR_INVALID_VALUE; + return SESSION_E_INVALID_RMT_IP; client = application_get (a->app_index); session_endpoint_update_for_app (&a->sep_ext, client, 1 /* is_connect */ ); @@ -1039,13 +1039,12 @@ vnet_connect (vnet_connect_args_t * a) rv = app_worker_connect_session (client_wrk, &a->sep, a->api_context); if (rv <= 0) return rv; + a->sep_ext.transport_proto = a->sep_ext.original_tp; } /* * Not connecting to a local server, propagate to transport */ - if (app_worker_connect_session (client_wrk, &a->sep, a->api_context)) - return VNET_API_ERROR_SESSION_CONNECT; - return 0; + return app_worker_connect_session (client_wrk, &a->sep, a->api_context); } int diff --git a/src/vnet/session/application.h b/src/vnet/session/application.h index 90b5a5a277e..00b60c33469 100644 --- a/src/vnet/session/application.h +++ b/src/vnet/session/application.h @@ -250,7 +250,7 @@ int app_worker_init_accepted (session_t * s); int app_worker_accept_notify (app_worker_t * app_wrk, session_t * s); int app_worker_init_connected (app_worker_t * app_wrk, session_t * s); int app_worker_connect_notify (app_worker_t * app_wrk, session_t * s, - u32 opaque); + session_error_t err, u32 opaque); int app_worker_close_notify (app_worker_t * app_wrk, session_t * s); int app_worker_transport_closed_notify (app_worker_t * app_wrk, session_t * s); @@ -299,7 +299,7 @@ app_cert_key_pair_t *app_cert_key_pair_get_default (); int mq_send_session_bound_cb (u32 app_wrk_index, u32 api_context, session_handle_t handle, int rv); int mq_send_session_connected_cb (u32 app_wrk_index, u32 api_context, - session_t * s, u8 is_fail); + session_t * s, session_error_t err); void mq_send_unlisten_reply (app_worker_t * app_wrk, session_handle_t sh, u32 context, int rv); diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h index b1ab847073a..7d5d044cc5a 100644 --- a/src/vnet/session/application_interface.h +++ b/src/vnet/session/application_interface.h @@ -42,7 +42,7 @@ typedef struct session_cb_vft_ /** Connection request callback */ int (*session_connected_callback) (u32 app_wrk_index, u32 opaque, - session_t * s, u8 code); + session_t * s, session_error_t code); /** Notify app that session is closing */ void (*session_disconnect_callback) (session_t * s); @@ -741,6 +741,24 @@ app_recv (app_session_t * s, u8 * data, u32 len) return app_recv_stream (s, data, len); } +/* *INDENT-OFF* */ +static char *session_error_str[] = { +#define _(sym, str) str, + foreach_session_error +#undef _ +}; +/* *INDENT-ON* */ + +static inline u8 * +format_session_error (u8 * s, va_list * args) +{ + session_error_t error = va_arg (*args, session_error_t); + if (-error >= 0 && -error < SESSION_N_ERRORS) + s = format (s, "%s", session_error_str[-error]); + else + s = format (s, "invalid session err %u", -error); + return s; +} #endif /* __included_uri_h__ */ /* diff --git a/src/vnet/session/application_local.c b/src/vnet/session/application_local.c index e2c1082d0b7..d54d1119ce6 100644 --- a/src/vnet/session/application_local.c +++ b/src/vnet/session/application_local.c @@ -96,7 +96,7 @@ ct_session_connect_notify (session_t * ss) segment_manager_t *sm; fifo_segment_t *seg; u64 segment_handle; - int is_fail = 0; + int err = 0; session_t *cs; u32 ss_index; @@ -108,13 +108,12 @@ ct_session_connect_notify (session_t * ss) seg = segment_manager_get_segment_w_lock (sm, ss->rx_fifo->segment_index); segment_handle = segment_manager_segment_handle (sm, seg); - if (app_worker_add_segment_notify (client_wrk, segment_handle)) + if ((err = app_worker_add_segment_notify (client_wrk, segment_handle))) { clib_warning ("failed to notify client %u of new segment", sct->client_wrk); segment_manager_segment_reader_unlock (sm); session_close (ss); - is_fail = 1; } else { @@ -149,8 +148,7 @@ ct_session_connect_notify (session_t * ss) return -1; } - if (app_worker_connect_notify (client_wrk, is_fail ? 0 : cs, - sct->client_opaque)) + if (app_worker_connect_notify (client_wrk, cs, err, sct->client_opaque)) { session_close (ss); return -1; @@ -371,7 +369,7 @@ ct_session_connect (transport_endpoint_cfg_t * tep) table_index = application_local_session_table (app); lh = session_lookup_local_endpoint (table_index, sep); if (lh == SESSION_DROP_HANDLE) - return VNET_API_ERROR_APP_CONNECT_FILTERED; + return SESSION_E_FILTERED; if (lh == SESSION_INVALID_HANDLE) goto global_scope; @@ -396,10 +394,10 @@ ct_session_connect (transport_endpoint_cfg_t * tep) global_scope: if (session_endpoint_is_local (sep)) - return VNET_API_ERROR_SESSION_CONNECT; + return SESSION_E_NOROUTE; if (!application_has_global_scope (app)) - return VNET_API_ERROR_APP_CONNECT_SCOPE; + return SESSION_E_SCOPE; fib_proto = session_endpoint_fib_proto (sep); table_index = session_lookup_get_index_for_fib (fib_proto, sep->fib_index); diff --git a/src/vnet/session/application_worker.c b/src/vnet/session/application_worker.c index 142b662b4d4..c17f43e90d1 100644 --- a/src/vnet/session/application_worker.c +++ b/src/vnet/session/application_worker.c @@ -173,7 +173,7 @@ app_worker_init_listener (app_worker_t * app_wrk, session_t * ls) /* Allocate segment manager. All sessions derived out of a listen session * have fifos allocated by the same segment manager. */ if (!(sm = app_worker_alloc_segment_manager (app_wrk))) - return -1; + return SESSION_E_ALLOC; /* Keep track of the segment manager for the listener or this worker */ hash_set (app_wrk->listeners_table, listen_session_get_handle (ls), @@ -182,12 +182,8 @@ app_worker_init_listener (app_worker_t * app_wrk, session_t * ls) if (transport_connection_is_cless (session_get_transport (ls))) { if (ls->rx_fifo) - { - clib_warning ("sharing of connectionless listeners not supported"); - return -1; - } - if (app_worker_alloc_session_fifos (sm, ls)) - return -1; + return SESSION_E_NOSUPPORT; + return app_worker_alloc_session_fifos (sm, ls); } return 0; } @@ -197,9 +193,10 @@ app_worker_start_listen (app_worker_t * app_wrk, app_listener_t * app_listener) { session_t *ls; + int rv; if (clib_bitmap_get (app_listener->workers, app_wrk->wrk_map_index)) - return VNET_API_ERROR_ADDRESS_IN_USE; + return SESSION_E_ALREADY_LISTENING; app_listener->workers = clib_bitmap_set (app_listener->workers, app_wrk->wrk_map_index, 1); @@ -207,15 +204,15 @@ app_worker_start_listen (app_worker_t * app_wrk, if (app_listener->session_index != SESSION_INVALID_INDEX) { ls = session_get (app_listener->session_index, 0); - if (app_worker_init_listener (app_wrk, ls)) - return -1; + if ((rv = app_worker_init_listener (app_wrk, ls))) + return rv; } if (app_listener->local_index != SESSION_INVALID_INDEX) { ls = session_get (app_listener->local_index, 0); - if (app_worker_init_listener (app_wrk, ls)) - return -1; + if ((rv = app_worker_init_listener (app_wrk, ls))) + return rv; } return 0; @@ -321,8 +318,7 @@ app_worker_init_connected (app_worker_t * app_wrk, session_t * s) if (!application_is_builtin_proxy (app)) { sm = app_worker_get_connect_segment_manager (app_wrk); - if (app_worker_alloc_session_fifos (sm, s)) - return -1; + return app_worker_alloc_session_fifos (sm, s); } if (app->cb_fns.fifo_tuning_callback) @@ -332,11 +328,12 @@ app_worker_init_connected (app_worker_t * app_wrk, session_t * s) } int -app_worker_connect_notify (app_worker_t * app_wrk, session_t * s, u32 opaque) +app_worker_connect_notify (app_worker_t * app_wrk, session_t * s, + session_error_t err, u32 opaque) { application_t *app = application_get (app_wrk->app_index); return app->cb_fns.session_connected_callback (app_wrk->wrk_index, opaque, - s, s == 0 /* is_fail */ ); + s, err); } int diff --git a/src/vnet/session/segment_manager.c b/src/vnet/session/segment_manager.c index ad5db656c77..154c7a61880 100644 --- a/src/vnet/session/segment_manager.c +++ b/src/vnet/session/segment_manager.c @@ -664,12 +664,12 @@ alloc_check: { clib_warning ("Added a segment, still can't allocate a fifo"); segment_manager_segment_reader_unlock (sm); - return SESSION_ERROR_NEW_SEG_NO_SPACE; + return SESSION_E_SEG_NO_SPACE2; } if ((new_fs_index = segment_manager_add_segment (sm, 0)) < 0) { clib_warning ("Failed to add new segment"); - return SESSION_ERROR_SEG_CREATE; + return SESSION_E_SEG_CREATE; } fs = segment_manager_get_segment_w_lock (sm, new_fs_index); alloc_fail = segment_manager_try_alloc_fifos (fs, thread_index, @@ -682,7 +682,7 @@ alloc_check: else { clib_warning ("Can't add new seg and no space to allocate fifos!"); - return SESSION_ERROR_NO_SPACE; + return SESSION_E_SEG_NO_SPACE; } } diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c index 33514008dd0..ac29627548c 100644 --- a/src/vnet/session/session.c +++ b/src/vnet/session/session.c @@ -736,7 +736,8 @@ session_main_flush_all_enqueue_events (u8 transport_proto) } static inline int -session_stream_connect_notify_inline (transport_connection_t * tc, u8 is_fail, +session_stream_connect_notify_inline (transport_connection_t * tc, + session_error_t err, session_state_t opened_state) { u32 opaque = 0, new_ti, new_si; @@ -764,8 +765,8 @@ session_stream_connect_notify_inline (transport_connection_t * tc, u8 is_fail, opaque = tc->s_index; - if (is_fail) - return app_worker_connect_notify (app_wrk, s, opaque); + if (err) + return app_worker_connect_notify (app_wrk, s, err, opaque); s = session_alloc_for_connection (tc); s->session_state = SESSION_STATE_CONNECTING; @@ -773,10 +774,10 @@ session_stream_connect_notify_inline (transport_connection_t * tc, u8 is_fail, new_si = s->session_index; new_ti = s->thread_index; - if (app_worker_init_connected (app_wrk, s)) + if ((err = app_worker_init_connected (app_wrk, s))) { session_free (s); - app_worker_connect_notify (app_wrk, 0, opaque); + app_worker_connect_notify (app_wrk, 0, err, opaque); return -1; } @@ -784,7 +785,7 @@ session_stream_connect_notify_inline (transport_connection_t * tc, u8 is_fail, s->session_state = opened_state; session_lookup_add_connection (tc, session_handle (s)); - if (app_worker_connect_notify (app_wrk, s, opaque)) + if (app_worker_connect_notify (app_wrk, s, SESSION_E_NONE, opaque)) { s = session_get (new_si, new_ti); session_free_w_fifos (s); @@ -795,17 +796,17 @@ session_stream_connect_notify_inline (transport_connection_t * tc, u8 is_fail, } int -session_stream_connect_notify (transport_connection_t * tc, u8 is_fail) +session_stream_connect_notify (transport_connection_t * tc, + session_error_t err) { - return session_stream_connect_notify_inline (tc, is_fail, - SESSION_STATE_READY); + return session_stream_connect_notify_inline (tc, err, SESSION_STATE_READY); } int -session_ho_stream_connect_notify (transport_connection_t * tc, u8 is_fail) +session_ho_stream_connect_notify (transport_connection_t * tc, + session_error_t err) { - return session_stream_connect_notify_inline (tc, is_fail, - SESSION_STATE_OPENED); + return session_stream_connect_notify_inline (tc, err, SESSION_STATE_OPENED); } typedef struct _session_switch_pool_args @@ -1116,7 +1117,7 @@ session_open_cl (u32 app_wrk_index, session_endpoint_t * rmt, u32 opaque) sh = session_handle (s); session_lookup_add_connection (tc, sh); - return app_worker_connect_notify (app_wrk, s, opaque); + return app_worker_connect_notify (app_wrk, s, SESSION_E_NONE, opaque); } int diff --git a/src/vnet/session/session.h b/src/vnet/session/session.h index 681b42d868d..a9f965d8f62 100644 --- a/src/vnet/session/session.h +++ b/src/vnet/session/session.h @@ -30,9 +30,6 @@ _(NOT_READY, "Session not ready packets") \ _(FIFO_FULL, "Packets dropped for lack of rx fifo space") \ _(EVENT_FIFO_FULL, "Events not sent for lack of event fifo space") \ _(API_QUEUE_FULL, "Sessions not created for lack of API queue space") \ -_(NEW_SEG_NO_SPACE, "Created segment, couldn't allocate a fifo pair") \ -_(NO_SPACE, "Couldn't allocate a fifo pair") \ -_(SEG_CREATE, "Couldn't create a new segment") typedef enum { @@ -40,7 +37,7 @@ typedef enum foreach_session_input_error #undef _ SESSION_N_ERROR, -} session_error_t; +} session_input_error_t; typedef struct session_tx_context_ { @@ -456,7 +453,8 @@ int session_enqueue_dgram_connection (session_t * s, session_dgram_hdr_t * hdr, vlib_buffer_t * b, u8 proto, u8 queue_event); -int session_stream_connect_notify (transport_connection_t * tc, u8 is_fail); +int session_stream_connect_notify (transport_connection_t * tc, + session_error_t err); int session_dgram_connect_notify (transport_connection_t * tc, u32 old_thread_index, session_t ** new_session); diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c index 6dcf06bd724..43ecf2b07e9 100644 --- a/src/vnet/session/session_api.c +++ b/src/vnet/session/session_api.c @@ -100,15 +100,12 @@ session_send_fds (vl_api_registration_t * reg, int fds[], int n_fds) { clib_error_t *error; if (vl_api_registration_file_index (reg) == VL_API_INVALID_FI) - { - clib_warning ("can't send memfd fd"); - return -1; - } + return SESSION_E_BAPI_NO_FD; error = vl_api_send_fd_msg (reg, fds, n_fds); if (error) { clib_error_report (error); - return -1; + return SESSION_E_BAPI_SEND_FD; } return 0; } @@ -146,7 +143,7 @@ mq_send_session_accepted_cb (session_t * s) app = application_get (app_wrk->app_index); app_mq = app_wrk->event_queue; if (mq_try_lock_and_alloc_msg (app_mq, msg)) - return -1; + return SESSION_E_MQ_MSG_ALLOC; evt = svm_msg_q_msg_data (app_mq, msg); clib_memset (evt, 0, sizeof (*evt)); @@ -265,7 +262,7 @@ mq_send_session_reset_cb (session_t * s) int mq_send_session_connected_cb (u32 app_wrk_index, u32 api_context, - session_t * s, u8 is_fail) + session_t * s, session_error_t err) { svm_msg_q_msg_t _msg, *msg = &_msg; session_connected_msg_t *mp; @@ -284,7 +281,7 @@ mq_send_session_connected_cb (u32 app_wrk_index, u32 api_context, } if (mq_try_lock_and_alloc_msg (app_mq, msg)) - return -1; + return SESSION_E_MQ_MSG_ALLOC; evt = svm_msg_q_msg_data (app_mq, msg); clib_memset (evt, 0, sizeof (*evt)); @@ -293,7 +290,7 @@ mq_send_session_connected_cb (u32 app_wrk_index, u32 api_context, clib_memset (mp, 0, sizeof (*mp)); mp->context = api_context; - if (is_fail) + if (err) goto done; if (session_has_transport (s)) @@ -301,7 +298,8 @@ mq_send_session_connected_cb (u32 app_wrk_index, u32 api_context, tc = session_get_transport (s); if (!tc) { - is_fail = 1; + clib_warning ("failed to retrieve transport!"); + err = SESSION_E_REFUSED; goto done; } @@ -336,8 +334,7 @@ mq_send_session_connected_cb (u32 app_wrk_index, u32 api_context, } done: - mp->retval = is_fail ? - clib_host_to_net_u32 (VNET_API_ERROR_SESSION_CONNECT) : 0; + mp->retval = err; svm_msg_q_add_and_unlock (app_mq, msg); return 0; @@ -365,7 +362,7 @@ mq_send_session_bound_cb (u32 app_wrk_index, u32 api_context, } if (mq_try_lock_and_alloc_msg (app_mq, msg)) - return -1; + return SESSION_E_MQ_MSG_ALLOC; evt = svm_msg_q_msg_data (app_mq, msg); clib_memset (evt, 0, sizeof (*evt)); diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c index 0290fe69544..c2a6ec921af 100644 --- a/src/vnet/session/session_node.c +++ b/src/vnet/session/session_node.c @@ -139,8 +139,7 @@ session_mq_connect_handler (void *data) { clib_warning ("connect returned: %U", format_vnet_api_errno, rv); app_wrk = application_get_worker (app, mp->wrk_index); - mq_send_session_connected_cb (app_wrk->wrk_index, mp->context, 0, - /* is_fail */ 1); + mq_send_session_connected_cb (app_wrk->wrk_index, mp->context, 0, rv); } vec_free (a->sep_ext.hostname); @@ -169,8 +168,7 @@ session_mq_connect_uri_handler (void *data) { clib_warning ("connect_uri returned: %d", rv); app_wrk = application_get_worker (app, 0 /* default wrk only */ ); - mq_send_session_connected_cb (app_wrk->wrk_index, mp->context, 0, - /* is_fail */ 1); + mq_send_session_connected_cb (app_wrk->wrk_index, mp->context, 0, rv); } } diff --git a/src/vnet/session/session_types.h b/src/vnet/session/session_types.h index a0360136b1d..ca5dcc1c123 100644 --- a/src/vnet/session/session_types.h +++ b/src/vnet/session/session_types.h @@ -433,6 +433,53 @@ typedef struct session_dgram_header_ STATIC_ASSERT (sizeof (session_dgram_hdr_t) == (SESSION_CONN_ID_LEN + 8), "session conn id wrong length"); + +#define foreach_session_error \ + _(NONE, "no error") \ + _(UNKNOWN, "generic/unknown error") \ + _(REFUSED, "refused") \ + _(TIMEDOUT, "timedout") \ + _(ALLOC, "obj/memory allocation error") \ + _(NOROUTE, "no route") \ + _(NOINTF, "no resolving interface") \ + _(NOIP, "no ip for lcl interface") \ + _(NOPORT, "no lcl port") \ + _(NOSUPPORT, "not supported") \ + _(PORTINUSE, "lcl port in use") \ + _(IPINUSE, "ip in use") \ + _(ALREADY_LISTENING, "ip port pair already listened on") \ + _(INVALID_RMT_IP, "invalid remote ip") \ + _(SEG_NO_SPACE, "Couldn't allocate a fifo pair") \ + _(SEG_NO_SPACE2, "Created segment, couldn't allocate a fifo pair") \ + _(SEG_CREATE, "Couldn't create a new segment") \ + _(FILTERED, "session filtered") \ + _(SCOPE, "scope not supported") \ + _(BAPI_NO_FD, "bapi doesn't have a socket fd") \ + _(BAPI_SEND_FD, "couldn't send fd over bapi socket fd") \ + _(BAPI_NO_REG, "app bapi registration not found") \ + _(MQ_MSG_ALLOC, "failed to alloc mq msg") \ + _(TLS_HANDSHAKE, "failed tls handshake") \ + +typedef enum session_error_p_ +{ +#define _(sym, str) SESSION_EP_##sym, + foreach_session_error +#undef _ + SESSION_N_ERRORS +} session_error_p_t; + +typedef enum session_error_ +{ +#define _(sym, str) SESSION_E_##sym = -SESSION_EP_##sym, + foreach_session_error +#undef _ +} session_error_t; + +/* Maintained for compatibility. Will be deprecated */ +#define SESSION_ERROR_SEG_CREATE SESSION_E_SEG_CREATE +#define SESSION_ERROR_NO_SPACE SESSION_E_SEG_NO_SPACE +#define SESSION_ERROR_NEW_SEG_NO_SPACE SESSION_E_SEG_NO_SPACE2 + #endif /* SRC_VNET_SESSION_SESSION_TYPES_H_ */ /* diff --git a/src/vnet/session/transport.c b/src/vnet/session/transport.c index 69046855c38..29c94f363ff 100644 --- a/src/vnet/session/transport.c +++ b/src/vnet/session/transport.c @@ -480,7 +480,7 @@ transport_alloc_local_port (u8 proto, ip46_address_t * ip) return -1; } -static clib_error_t * +static session_error_t transport_get_interface_ip (u32 sw_if_index, u8 is_ip4, ip46_address_t * addr) { if (is_ip4) @@ -488,9 +488,7 @@ transport_get_interface_ip (u32 sw_if_index, u8 is_ip4, ip46_address_t * addr) ip4_address_t *ip4; ip4 = ip_interface_get_first_ip (sw_if_index, 1); if (!ip4) - return clib_error_return (0, "no routable ip4 address on %U", - format_vnet_sw_if_index_name, - vnet_get_main (), sw_if_index); + return SESSION_E_NOIP; addr->ip4.as_u32 = ip4->as_u32; } else @@ -498,15 +496,13 @@ transport_get_interface_ip (u32 sw_if_index, u8 is_ip4, ip46_address_t * addr) ip6_address_t *ip6; ip6 = ip_interface_get_first_ip (sw_if_index, 0); if (ip6 == 0) - return clib_error_return (0, "no routable ip6 addresses on %U", - format_vnet_sw_if_index_name, - vnet_get_main (), sw_if_index); + return SESSION_E_NOIP; clib_memcpy_fast (&addr->ip6, ip6, sizeof (*ip6)); } return 0; } -static clib_error_t * +static session_error_t transport_find_local_ip_for_remote (u32 sw_if_index, transport_endpoint_t * rmt, ip46_address_t * lcl_addr) @@ -526,14 +522,11 @@ transport_find_local_ip_for_remote (u32 sw_if_index, /* Couldn't find route to destination. Bail out. */ if (fei == FIB_NODE_INDEX_INVALID) - return clib_error_return (0, "no route to %U", format_ip46_address, - &rmt->ip, (rmt->is_ip4 == 0) + 1); + return SESSION_E_NOROUTE; sw_if_index = fib_entry_get_resolving_interface (fei); if (sw_if_index == ENDPOINT_INVALID_INDEX) - return clib_error_return (0, "no resolving interface for %U", - format_ip46_address, &rmt->ip, - (rmt->is_ip4 == 0) + 1); + return SESSION_E_NOINTF; } clib_memset (lcl_addr, 0, sizeof (*lcl_addr)); @@ -545,7 +538,7 @@ transport_alloc_local_endpoint (u8 proto, transport_endpoint_cfg_t * rmt_cfg, ip46_address_t * lcl_addr, u16 * lcl_port) { transport_endpoint_t *rmt = (transport_endpoint_t *) rmt_cfg; - clib_error_t *error; + session_error_t error; int port; u32 tei; @@ -557,10 +550,7 @@ transport_alloc_local_endpoint (u8 proto, transport_endpoint_cfg_t * rmt_cfg, error = transport_find_local_ip_for_remote (rmt_cfg->peer.sw_if_index, rmt, lcl_addr); if (error) - { - clib_error_report (error); - return -1; - } + return error; } else { @@ -576,10 +566,7 @@ transport_alloc_local_endpoint (u8 proto, transport_endpoint_cfg_t * rmt_cfg, { port = transport_alloc_local_port (proto, lcl_addr); if (port < 1) - { - clib_warning ("Failed to allocate src port"); - return -1; - } + return SESSION_E_NOPORT; *lcl_port = port; } else @@ -588,7 +575,7 @@ transport_alloc_local_endpoint (u8 proto, transport_endpoint_cfg_t * rmt_cfg, tei = transport_endpoint_lookup (&local_endpoints_table, proto, lcl_addr, port); if (tei != ENDPOINT_INVALID_INDEX) - return -1; + return SESSION_E_PORTINUSE; transport_endpoint_mark_used (proto, lcl_addr, port); *lcl_port = port; diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c index d85225b9172..b1ae37409fd 100644 --- a/src/vnet/tcp/tcp.c +++ b/src/vnet/tcp/tcp.c @@ -738,10 +738,7 @@ tcp_alloc_custom_local_endpoint (tcp_main_t * tm, ip46_address_t * lcl_addr, } port = transport_alloc_local_port (TRANSPORT_PROTO_TCP, lcl_addr); if (port < 1) - { - clib_warning ("Failed to allocate src port"); - return -1; - } + return SESSION_E_NOPORT; *lcl_port = port; return 0; } @@ -767,7 +764,7 @@ tcp_session_open (transport_endpoint_cfg_t * rmt) rmt, &lcl_addr, &lcl_port); if (rv) - return -1; + return rv; /* * Create connection and send SYN diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c index 713e11fd896..403acad1700 100755 --- a/src/vnet/tcp/tcp_input.c +++ b/src/vnet/tcp/tcp_input.c @@ -1985,7 +1985,8 @@ tcp46_syn_sent_inline (vlib_main_t * vm, vlib_node_runtime_t * node, /* Notify app that we have connection. If session layer can't * allocate session send reset */ - if (session_stream_connect_notify (&new_tc0->connection, 0)) + if (session_stream_connect_notify (&new_tc0->connection, + SESSION_E_NONE)) { tcp_send_reset_w_pkt (new_tc0, b0, my_thread_index, is_ip4); tcp_connection_cleanup (new_tc0); @@ -2006,7 +2007,8 @@ tcp46_syn_sent_inline (vlib_main_t * vm, vlib_node_runtime_t * node, new_tc0->state = TCP_STATE_SYN_RCVD; /* Notify app that we have connection */ - if (session_stream_connect_notify (&new_tc0->connection, 0)) + if (session_stream_connect_notify (&new_tc0->connection, + SESSION_E_NONE)) { tcp_connection_cleanup (new_tc0); tcp_send_reset_w_pkt (tc0, b0, my_thread_index, is_ip4); diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c index a68d5269abd..095f3602557 100644 --- a/src/vnet/tcp/tcp_output.c +++ b/src/vnet/tcp/tcp_output.c @@ -1472,7 +1472,7 @@ tcp_timer_retransmit_syn_handler (tcp_connection_t * tc) /* Active open establish timeout */ if (tc->rto >= TCP_ESTABLISH_TIME >> 1) { - session_stream_connect_notify (&tc->connection, 1 /* fail */ ); + session_stream_connect_notify (&tc->connection, SESSION_E_TIMEDOUT); tcp_connection_cleanup (tc); return; } diff --git a/src/vnet/tls/tls.c b/src/vnet/tls/tls.c index 88ce3591bb6..7a172b88928 100644 --- a/src/vnet/tls/tls.c +++ b/src/vnet/tls/tls.c @@ -217,7 +217,7 @@ tls_notify_app_accept (tls_ctx_t * ctx) } int -tls_notify_app_connected (tls_ctx_t * ctx, u8 is_failed) +tls_notify_app_connected (tls_ctx_t * ctx, session_error_t err) { session_t *app_session; app_worker_t *app_wrk; @@ -229,7 +229,7 @@ tls_notify_app_connected (tls_ctx_t * ctx, u8 is_failed) return -1; } - if (is_failed) + if (err) goto failed; app_session = session_get (ctx->c_s_index, ctx->c_thread_index); @@ -238,12 +238,12 @@ tls_notify_app_connected (tls_ctx_t * ctx, u8 is_failed) app_session->session_type = session_type_from_proto_and_ip (TRANSPORT_PROTO_TLS, ctx->tcp_is_ip4); - if (app_worker_init_connected (app_wrk, app_session)) + if ((err = app_worker_init_connected (app_wrk, app_session))) goto failed; app_session->session_state = SESSION_STATE_CONNECTING; if (app_worker_connect_notify (app_wrk, app_session, - ctx->parent_app_api_context)) + SESSION_E_NONE, ctx->parent_app_api_context)) { TLS_DBG (1, "failed to notify app"); tls_disconnect (ctx->tls_ctx_handle, vlib_get_thread_index ()); @@ -260,7 +260,8 @@ failed: session_free (session_get (ctx->c_s_index, ctx->c_thread_index)); ctx->no_app_session = 1; tls_disconnect (ctx->tls_ctx_handle, vlib_get_thread_index ()); - return app_worker_connect_notify (app_wrk, 0, ctx->parent_app_api_context); + return app_worker_connect_notify (app_wrk, 0, err, + ctx->parent_app_api_context); } static inline void @@ -452,7 +453,7 @@ tls_app_rx_callback (session_t * tls_session) int tls_session_connected_callback (u32 tls_app_index, u32 ho_ctx_index, - session_t * tls_session, u8 is_fail) + session_t * tls_session, session_error_t err) { session_t *app_session; tls_ctx_t *ho_ctx, *ctx; @@ -460,7 +461,7 @@ tls_session_connected_callback (u32 tls_app_index, u32 ho_ctx_index, ho_ctx = tls_ctx_half_open_get (ho_ctx_index); - if (is_fail) + if (err) { app_worker_t *app_wrk; u32 api_context; @@ -470,7 +471,7 @@ tls_session_connected_callback (u32 tls_app_index, u32 ho_ctx_index, if (app_wrk) { api_context = ho_ctx->c_s_index; - app_worker_connect_notify (app_wrk, 0, api_context); + app_worker_connect_notify (app_wrk, 0, err, api_context); } tls_ctx_half_open_reader_unlock (); tls_ctx_half_open_free (ho_ctx_index); diff --git a/src/vnet/tls/tls.h b/src/vnet/tls/tls.h index 15d06db6563..1281e3d62c9 100644 --- a/src/vnet/tls/tls.h +++ b/src/vnet/tls/tls.h @@ -126,7 +126,7 @@ int tls_add_vpp_q_tx_evt (session_t * s); int tls_add_vpp_q_builtin_tx_evt (session_t * s); int tls_add_vpp_q_builtin_rx_evt (session_t * s); int tls_notify_app_accept (tls_ctx_t * ctx); -int tls_notify_app_connected (tls_ctx_t * ctx, u8 is_failed); +int tls_notify_app_connected (tls_ctx_t * ctx, session_error_t err); void tls_notify_app_enqueue (tls_ctx_t * ctx, session_t * app_session); void tls_disconnect_transport (tls_ctx_t * ctx); #endif /* SRC_VNET_TLS_TLS_H_ */ diff --git a/src/vnet/udp/udp.c b/src/vnet/udp/udp.c index 3632204f863..65d50fff395 100644 --- a/src/vnet/udp/udp.c +++ b/src/vnet/udp/udp.c @@ -418,16 +418,18 @@ udp_open_connection (transport_endpoint_cfg_t * rmt) udp_connection_t *uc; ip46_address_t lcl_addr; u16 lcl_port; + int rv; - if (transport_alloc_local_endpoint (TRANSPORT_PROTO_UDP, rmt, &lcl_addr, - &lcl_port)) - return -1; + rv = transport_alloc_local_endpoint (TRANSPORT_PROTO_UDP, rmt, &lcl_addr, + &lcl_port); + if (rv) + return rv; if (udp_is_valid_dst_port (lcl_port, rmt->is_ip4)) { /* If specific source port was requested abort */ if (rmt->peer.port) - return -1; + return SESSION_E_PORTINUSE; /* Try to find a port that's not used */ while (udp_is_valid_dst_port (lcl_port, rmt->is_ip4)) @@ -435,10 +437,7 @@ udp_open_connection (transport_endpoint_cfg_t * rmt) lcl_port = transport_alloc_local_port (TRANSPORT_PROTO_UDP, &lcl_addr); if (lcl_port < 1) - { - clib_warning ("Failed to allocate src port"); - return -1; - } + return SESSION_E_PORTINUSE; } } |