Mercurial > hg > freeDiameter
diff freeDiameter/sctps.c @ 29:5ba91682f0bc
Added a test for cnxctx (tbc) and fixed some bugs
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Wed, 28 Oct 2009 15:19:50 +0900 |
parents | b3a1773e9f46 |
children | 26685c67d387 |
line wrap: on
line diff
--- a/freeDiameter/sctps.c Mon Oct 26 18:07:24 2009 +0900 +++ b/freeDiameter/sctps.c Wed Oct 28 15:19:50 2009 +0900 @@ -72,10 +72,16 @@ uint16_t strid; TRACE_ENTRY("%p", arg); + CHECK_PARAMS_DO(conn && (conn->cc_socket > 0), goto out); - CHECK_PARAMS_DO(conn && (conn->cc_socket > 0), goto out); + /* Set the thread name */ + { + char buf[48]; + snprintf(buf, sizeof(buf), "Demuxer (%d)", conn->cc_socket); + fd_log_threadname ( buf ); + } + ASSERT( conn->cc_proto == IPPROTO_SCTP ); - ASSERT( conn->cc_tls == 1 ); ASSERT( Target_Queue(conn) ); ASSERT( conn->cc_sctps_data.array ); @@ -114,11 +120,17 @@ struct cnxctx *cnx; TRACE_ENTRY("%p", arg); - CHECK_PARAMS_DO(ctx && ctx->raw_recv && ctx->parent, goto error); cnx = ctx->parent; ASSERT( Target_Queue(cnx) ); + /* Set the thread name */ + { + char buf[48]; + snprintf(buf, sizeof(buf), "Decipher (%hu@%d)", ctx->strid, cnx->cc_socket); + fd_log_threadname ( buf ); + } + CHECK_FCT_DO(fd_tls_rcvthr_core(cnx, ctx->strid ? ctx->session : cnx->cc_tls_para.session), /* continue */); error: CHECK_FCT_DO( fd_event_send( Target_Queue(cnx), FDEVP_CNX_ERROR, 0, NULL), /* continue or destroy everything? */); @@ -208,6 +220,7 @@ struct fd_list list; /* list of sr_data, ordered by key.size then key.data */ pthread_rwlock_t lock; struct cnxctx *parent; + /* Add another list to chain in a global list to implement a garbage collector on sessions */ }; /* Saved master session data for resuming sessions */ @@ -218,7 +231,7 @@ }; /* The level at which we debug session resuming */ -#define SR_LEVEL FULL +#define SR_LEVEL (FULL + 1) /* Initialize the store area for a connection */ static int store_init(struct cnxctx * conn) @@ -302,9 +315,9 @@ int ret = 0; CHECK_PARAMS_DO( sto && key.data && data.data, return -1 ); - TRACE_DEBUG_BUFFER(SR_LEVEL, "Session store [key ", key.data, key.size < 16 ? key.size : 16, "]"); CHECK_POSIX_DO( pthread_rwlock_wrlock(&sto->lock), return -1 ); + TRACE_DEBUG_BUFFER(SR_LEVEL, "Session store [key ", key.data, key.size, "]"); li = find_or_next(sto, key, &match); if (match) { @@ -312,8 +325,10 @@ /* Check the data is the same */ if ((data.size != sr->data.size) || memcmp(data.data, sr->data.data, data.size)) { - TRACE_DEBUG(INFO, "GnuTLS tried to store a session with same key and different data!"); + TRACE_DEBUG(SR_LEVEL, "GnuTLS tried to store a session with same key and different data!"); ret = -1; + } else { + TRACE_DEBUG(SR_LEVEL, "GnuTLS tried to store a session with same key and same data, skipped."); } goto out; } @@ -349,9 +364,9 @@ int ret = 0; CHECK_PARAMS_DO( sto && key.data, return -1 ); - TRACE_DEBUG_BUFFER(SR_LEVEL, "Session delete [key ", key.data, key.size < 16 ? key.size : 16, "]"); CHECK_POSIX_DO( pthread_rwlock_wrlock(&sto->lock), return -1 ); + TRACE_DEBUG_BUFFER(SR_LEVEL, "Session delete [key ", key.data, key.size, "]"); li = find_or_next(sto, key, &match); if (match) { @@ -381,9 +396,9 @@ gnutls_datum_t error = { NULL, 0 }; CHECK_PARAMS_DO( sto && key.data, return error ); - TRACE_DEBUG_BUFFER(SR_LEVEL, "Session fetch [key ", key.data, key.size < 16 ? key.size : 16, "]"); CHECK_POSIX_DO( pthread_rwlock_rdlock(&sto->lock), return error ); + TRACE_DEBUG_BUFFER(SR_LEVEL, "Session fetch [key ", key.data, key.size, "]"); li = find_or_next(sto, key, &match); if (match) { @@ -393,6 +408,7 @@ memcpy(res.data, sr->data.data, res.size); } out: + TRACE_DEBUG(SR_LEVEL, "Fetched (%p, %d) from store %p", res.data, res.size, sto); CHECK_POSIX_DO( pthread_rwlock_unlock(&sto->lock), return error); return res; } @@ -416,10 +432,24 @@ struct sctps_ctx * ctx = (struct sctps_ctx *) arg; TRACE_ENTRY("%p", arg); + /* Set the thread name */ + { + char buf[48]; + snprintf(buf, sizeof(buf), "Handshake resume (%hu@%d)", ctx->strid, ctx->parent->cc_socket); + fd_log_threadname ( buf ); + } + TRACE_DEBUG(FULL, "Starting TLS resumed handshake on stream %hu", ctx->strid); CHECK_GNUTLS_DO( gnutls_handshake( ctx->session ), return NULL); - /* We can trace success of resuming handshake by using gnutls_session_is_resumed */ + if (TRACE_BOOL(FULL)) { + int resumed = gnutls_session_is_resumed(ctx->session); + if (resumed) { + fd_log_debug("Session was resumed successfully on stream %hu (conn: '%s')\n", ctx->strid, fd_cnx_getid(ctx->parent)); + } else { + fd_log_debug("Session was NOT resumed (full handshake) on stream %hu (conn: '%s')\n", ctx->strid, fd_cnx_getid(ctx->parent)); + } + } /* Finish */ return arg; @@ -466,7 +496,7 @@ } /* Handshake other streams, after full handshake on the master session */ -int fd_sctps_handshake_others(struct cnxctx * conn, char * priority) +int fd_sctps_handshake_others(struct cnxctx * conn, char * priority, void * alt_creds) { uint16_t i; int errors = 0; @@ -486,7 +516,7 @@ /* Initialize the session objects and start the handshake in a separate thread */ for (i = 1; i < conn->cc_sctp_para.pairs; i++) { /* Set credentials and priority */ - CHECK_FCT( fd_tls_prepare(&conn->cc_sctps_data.array[i].session, conn->cc_tls_para.mode, priority) ); + CHECK_FCT( fd_tls_prepare(&conn->cc_sctps_data.array[i].session, conn->cc_tls_para.mode, priority, alt_creds) ); /* For the client, copy data from master session; for the server, set session resuming pointers */ if (conn->cc_tls_para.mode == GNUTLS_CLIENT) { @@ -549,6 +579,26 @@ return; } +static void * bye_th(void * arg) +{ + struct sctps_ctx * ctx = (struct sctps_ctx *) arg; + TRACE_ENTRY("%p", arg); + + /* Set the thread name */ + { + char buf[48]; + snprintf(buf, sizeof(buf), "gnutls_bye (%hu@%d)", ctx->strid, ctx->parent->cc_socket); + fd_log_threadname ( buf ); + } + + CHECK_GNUTLS_DO( gnutls_bye(ctx->session, GNUTLS_SHUT_RDWR), /* Continue */ ); + + /* Finish */ + return arg; +} + + + /* Destroy a wrapper context */ void fd_sctps_destroy(struct cnxctx * conn) { @@ -559,11 +609,14 @@ /* Terminate all receiving threads in case we did not do it yet */ fd_sctps_stopthreads(conn); - /* End all TLS sessions -- maybe we should do it in parallel ? */ - for (i = 0; i < conn->cc_sctp_para.pairs; i++) { - CHECK_GNUTLS_DO( gnutls_bye(conn->cc_sctps_data.array[i].session, GNUTLS_SHUT_RDWR), /* Continue */ ); + /* End all TLS sessions, in parallel */ + for (i = 1; i < conn->cc_sctp_para.pairs; i++) { + CHECK_POSIX_DO( pthread_create( &conn->cc_sctps_data.array[i].thr, NULL, bye_th, &conn->cc_sctps_data.array[i] ), break ); } - + for (--i; i > 0; --i) { + CHECK_POSIX_DO( pthread_join( conn->cc_sctps_data.array[i].thr, NULL ), continue ); + } +skip: /* Now, stop the demux thread */ CHECK_FCT_DO( fd_thr_term(&conn->cc_rcvthr), /* continue */ ); @@ -571,7 +624,8 @@ for (i = 0; i < conn->cc_sctp_para.pairs; i++) { fd_event_destroy( &conn->cc_sctps_data.array[i].raw_recv, free ); free(conn->cc_sctps_data.array[i].partial.buf); - gnutls_deinit(conn->cc_sctps_data.array[i].session); + if (i > 0) + gnutls_deinit(conn->cc_sctps_data.array[i].session); } /* Free the array itself now */