Navigation


Changeset 706:4ffbc9f1e922 in freeDiameter for libfdcore/cnxctx.c


Ignore:
Timestamp:
Feb 9, 2011, 3:26:58 PM (13 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Large UNTESTED commit with the following changes:

  • Improved DiameterIdentity? handling (esp. interationalization issues), and improve efficiency of some string operations in peers, sessions, and dictionary modules (closes #7)
  • Cleanup in the session module to free only unreferenced sessions (#16)
  • Removed fd_cpu_flush_cache(), replaced by more robust alternatives.
  • Improved peer state machine algorithm to counter SCTP multistream race condition.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libfdcore/cnxctx.c

    r662 r706  
    5151 */
    5252
    53 /* Note: this file could be moved to libfreeDiameter instead, but since it uses gnuTLS we prefer to keep it in the daemon */
    54 
    5553/* Lifetime of a cnxctx object:
    5654 * 1) Creation
     
    158156        TRACE_DEBUG(INFO, "This function should never been called when SCTP is disabled...");
    159157        ASSERT(0);
    160         CHECK_FCT_DO( ENOTSUP, );
    161         return NULL;
     158        CHECK_FCT_DO( ENOTSUP, return NULL);
    162159#else /* DISABLE_SCTP */
    163160        struct cnxctx * cnx = NULL;
     
    249246                int  rc;
    250247               
    251                 /* Numeric values for debug */
    252248                rc = getnameinfo((sSA *)&ss, sSAlen(&ss), addrbuf, sizeof(addrbuf), portbuf, sizeof(portbuf), NI_NUMERICHOST | NI_NUMERICSERV);
    253249                if (rc) {
     
    256252                }
    257253               
    258                 snprintf(cli->cc_id, sizeof(cli->cc_id), "{%s} (%d) <- [%s]:%s (%d)",
    259                                 IPPROTO_NAME(cli->cc_proto), serv->cc_socket,
    260                                 addrbuf, portbuf, cli->cc_socket);
    261                
    262                 /* Name for log messages */
     254                /* Numeric values for debug... */
     255                snprintf(cli->cc_id, sizeof(cli->cc_id), "%s from [%s]:%s (%d<-%d)",
     256                                IPPROTO_NAME(cli->cc_proto), addrbuf, portbuf, serv->cc_socket, cli->cc_socket);
     257               
     258               
     259                /* ...Name for log messages */
    263260                rc = getnameinfo((sSA *)&ss, sSAlen(&ss), cli->cc_remid, sizeof(cli->cc_remid), NULL, 0, 0);
    264261                if (rc)
     
    334331                int  rc;
    335332               
    336                 /* Numeric values for debug */
     333                /* Numeric values for debug... */
    337334                rc = getnameinfo(sa, addrlen, addrbuf, sizeof(addrbuf), portbuf, sizeof(portbuf), NI_NUMERICHOST | NI_NUMERICSERV);
    338335                if (rc) {
     
    341338                }
    342339               
    343                 snprintf(cnx->cc_id, sizeof(cnx->cc_id), "{TCP} -> [%s]:%s (%d)", addrbuf, portbuf, cnx->cc_socket);
    344                
    345                 /* Name for log messages */
     340                snprintf(cnx->cc_id, sizeof(cnx->cc_id), "TCP to [%s]:%s (%d)", addrbuf, portbuf, cnx->cc_socket);
     341               
     342                /* ...Name for log messages */
    346343                rc = getnameinfo(sa, addrlen, cnx->cc_remid, sizeof(cnx->cc_remid), NULL, 0, 0);
    347344                if (rc)
     
    356353{
    357354#ifdef DISABLE_SCTP
    358         TRACE_DEBUG(INFO, "This function should never been called when SCTP is disabled...");
     355        TRACE_DEBUG(INFO, "This function should never be called when SCTP is disabled...");
    359356        ASSERT(0);
    360         CHECK_FCT_DO( ENOTSUP, );
    361         return NULL;
     357        CHECK_FCT_DO( ENOTSUP, return NULL);
    362358#else /* DISABLE_SCTP */
    363359        int sock = 0;
     
    416412                int  rc;
    417413               
    418                 /* Numeric values for debug */
     414                /* Numeric values for debug... */
    419415                rc = getnameinfo((sSA *)&primary, sSAlen(&primary), addrbuf, sizeof(addrbuf), portbuf, sizeof(portbuf), NI_NUMERICHOST | NI_NUMERICSERV);
    420416                if (rc) {
     
    423419                }
    424420               
    425                 snprintf(cnx->cc_id, sizeof(cnx->cc_id), "{SCTP} -> [%s]:%s (%d)", addrbuf, portbuf, cnx->cc_socket);
    426                
    427                 /* Name for log messages */
     421                snprintf(cnx->cc_id, sizeof(cnx->cc_id), "SCTP to [%s]:%s (%d)", addrbuf, portbuf, cnx->cc_socket);
     422               
     423                /* ...Name for log messages */
    428424                rc = getnameinfo((sSA *)&primary, sSAlen(&primary), cnx->cc_remid, sizeof(cnx->cc_remid), NULL, 0, 0);
    429425                if (rc)
     
    454450
    455451/* Set the hostname to check during handshake */
    456 void fd_cnx_sethostname(struct cnxctx * conn, char * hn)
     452void fd_cnx_sethostname(struct cnxctx * conn, DiamId_t hn)
    457453{
    458454        CHECK_PARAMS_DO( conn, return );
     
    460456}
    461457
     458/* We share a lock with many threads but we hold it only very short time so it is OK */
     459static pthread_mutex_t state_lock = PTHREAD_MUTEX_INITIALIZER;
     460uint32_t fd_cnx_getstate(struct cnxctx * conn)
     461{
     462        uint32_t st;
     463        CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } );
     464        st = conn->cc_state;
     465        CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } );
     466        return st;
     467}
     468int  fd_cnx_teststate(struct cnxctx * conn, uint32_t flag)
     469{
     470        uint32_t st;
     471        CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } );
     472        st = conn->cc_state;
     473        CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } );
     474        return st & flag;
     475}
     476void fd_cnx_addstate(struct cnxctx * conn, uint32_t orstate)
     477{
     478        CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } );
     479        conn->cc_state |= orstate;
     480        CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } );
     481}
     482void fd_cnx_setstate(struct cnxctx * conn, uint32_t abstate)
     483{
     484        CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } );
     485        conn->cc_state = abstate;
     486        CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } );
     487}
     488
     489
    462490/* Return the TLS state of a connection */
    463491int fd_cnx_getTLS(struct cnxctx * conn)
    464492{
    465493        CHECK_PARAMS_DO( conn, return 0 );
    466         fd_cpu_flush_cache();
    467         return conn->cc_status & CC_STATUS_TLS;
    468 }
     494        return fd_cnx_teststate(conn, CC_STATUS_TLS);
     495}
     496
     497/* Return true if the connection supports unordered delivery of messages */
     498int fd_cnx_isMultichan(struct cnxctx * conn)
     499{
     500        CHECK_PARAMS_DO( conn, return 0 );
     501        #ifdef DISABLE_SCTP
     502        if (conn->cc_proto == IPPROTO_SCTP)
     503                return (conn->cc_sctp_para.str_in > 1) || (conn->cc_sctp_para.str_out > 1);
     504        #endif /* DISABLE_SCTP */
     505        return 0;
     506}
     507
    469508
    470509/* Get the list of endpoints (IP addresses) of the local and remote peers on this connection */
     
    508547}
    509548
    510 /* Retrieve a list of all IP addresses of the local system from the kernel, using */
     549/* Retrieve a list of all IP addresses of the local system from the kernel, using getifaddrs */
    511550int fd_cnx_get_local_eps(struct fd_list * list)
    512551{
    513552        struct ifaddrs *iflist, *cur;
     553       
    514554        CHECK_SYS(getifaddrs(&iflist));
    515555       
     
    543583        CHECK_PARAMS_DO( conn, goto fatal );
    544584       
    545         TRACE_DEBUG(FULL, "Error flag set for socket %d (%s / %s)", conn->cc_socket, conn->cc_remid, conn->cc_id);
     585        TRACE_DEBUG(FULL, "Error flag set for socket %d (%s, %s)", conn->cc_socket, conn->cc_id, conn->cc_remid);
    546586       
    547587        /* Mark the error */
    548         fd_cpu_flush_cache();
    549         conn->cc_status |= CC_STATUS_ERROR;
     588        fd_cnx_addstate(conn, CC_STATUS_ERROR);
    550589       
    551590        /* Report the error if not reported yet, and not closing */
    552         if ((!(conn->cc_status & CC_STATUS_CLOSING )) && (!(conn->cc_status & CC_STATUS_SIGNALED )))  {
     591        if (!fd_cnx_teststate(conn, CC_STATUS_CLOSING | CC_STATUS_SIGNALED ))  {
    553592                TRACE_DEBUG(FULL, "Sending FDEVP_CNX_ERROR event");
    554                 CHECK_FCT_DO( fd_event_send( Target_Queue(conn), FDEVP_CNX_ERROR, 0, NULL), goto fatal);
    555                 conn->cc_status |= CC_STATUS_SIGNALED;
    556         }
    557         fd_cpu_flush_cache();
     593                CHECK_FCT_DO( fd_event_send( fd_cnx_target_queue(conn), FDEVP_CNX_ERROR, 0, NULL), goto fatal);
     594                fd_cnx_addstate(conn, CC_STATUS_SIGNALED);
     595        }
    558596        return;
    559597fatal:
    560598        /* An unrecoverable error occurred, stop the daemon */
     599        ASSERT(0);
    561600        CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, 0, NULL), );       
    562601}
     
    583622        /* Handle special case of timeout */
    584623        if ((ret < 0) && (errno == EAGAIN)) {
    585                 fd_cpu_flush_cache();
    586                 if (! (conn->cc_status & CC_STATUS_CLOSING))
     624                if (! fd_cnx_teststate(conn, CC_STATUS_CLOSING ))
    587625                        goto again; /* don't care, just ignore */
    588626                if (!timedout) {
     
    592630        }
    593631       
    594         CHECK_SYS_DO(ret, /* continue */);
    595        
    596632        /* Mark the error */
    597         if (ret <= 0)
     633        if (ret <= 0) {
     634                CHECK_SYS_DO(ret, /* continue, this is only used to log the error here */);
    598635                fd_cnx_markerror(conn);
     636        }
    599637       
    600638        return ret;
     
    610648        /* Handle special case of timeout */
    611649        if ((ret < 0) && (errno == EAGAIN)) {
    612                 fd_cpu_flush_cache();
    613                 if (! (conn->cc_status & CC_STATUS_CLOSING))
     650                if (! fd_cnx_teststate(conn, CC_STATUS_CLOSING ))
    614651                        goto again; /* don't care, just ignore */
    615652                if (!timedout) {
     
    643680       
    644681        ASSERT( conn->cc_proto == IPPROTO_TCP );
    645         ASSERT( ! (conn->cc_status & CC_STATUS_TLS) );
    646         ASSERT( Target_Queue(conn) );
     682        ASSERT( ! fd_cnx_teststate(conn, CC_STATUS_TLS ) );
     683        ASSERT( fd_cnx_target_queue(conn) );
    647684       
    648685        /* Receive from a TCP connection: we have to rebuild the message boundaries */
     
    666703
    667704                /* Check the received word is a valid begining of a Diameter message */
    668                 if ((header[0] != DIAMETER_VERSION)     /* defined in <libfreeDiameter.h> */
     705                if ((header[0] != DIAMETER_VERSION)     /* defined in <libfdproto.h> */
    669706                   || (length > DIAMETER_MSG_SIZE_MAX)) { /* to avoid too big mallocs */
    670707                        /* The message is suspect */
     
    691728               
    692729                /* We have received a complete message, pass it to the daemon */
    693                 fd_cpu_flush_cache();
    694                 CHECK_FCT_DO( fd_event_send( Target_Queue(conn), FDEVP_CNX_MSG_RECV, length, newmsg), /* continue or destroy everything? */);
     730                CHECK_FCT_DO( fd_event_send( fd_cnx_target_queue(conn), FDEVP_CNX_MSG_RECV, length, newmsg), /* continue or destroy everything? */);
    695731               
    696732        } while (conn->cc_loop);
     
    726762       
    727763        ASSERT( conn->cc_proto == IPPROTO_SCTP );
    728         ASSERT( ! (conn->cc_status & CC_STATUS_TLS) );
    729         ASSERT( Target_Queue(conn) );
     764        ASSERT( ! fd_cnx_teststate(conn, CC_STATUS_TLS ) );
     765        ASSERT( fd_cnx_target_queue(conn) );
    730766       
    731767        do {
    732                 fd_cpu_flush_cache();
    733                 CHECK_FCT_DO( fd_sctp_recvmeta(conn->cc_socket, NULL, &buf, &bufsz, &event, &conn->cc_status), goto fatal );
     768                CHECK_FCT_DO( fd_sctp_recvmeta(conn, NULL, &buf, &bufsz, &event), goto fatal );
    734769                if (event == FDEVP_CNX_ERROR) {
    735770                        fd_cnx_markerror(conn);
     
    742777                }
    743778               
    744                 fd_cpu_flush_cache();
    745                 CHECK_FCT_DO( fd_event_send( Target_Queue(conn), event, bufsz, buf), goto fatal );
     779                CHECK_FCT_DO( fd_event_send( fd_cnx_target_queue(conn), event, bufsz, buf), goto fatal );
    746780               
    747781        } while (conn->cc_loop || (event != FDEVP_CNX_MSG_RECV));
     
    763797        TRACE_ENTRY("%p %i", conn, loop);
    764798       
    765         CHECK_PARAMS( conn && Target_Queue(conn) && (!(conn->cc_status & CC_STATUS_TLS)) && (!conn->cc_loop));
     799        CHECK_PARAMS( conn && fd_cnx_target_queue(conn) && (!fd_cnx_teststate(conn, CC_STATUS_TLS)) && (!conn->cc_loop));
    766800       
    767801        /* Release resources in case of a previous call was already made */
     
    803837                        switch (ret) {
    804838                                case GNUTLS_E_REHANDSHAKE:
    805                                         fd_cpu_flush_cache();
    806                                         if (!(conn->cc_status & CC_STATUS_CLOSING))
     839                                        if (!fd_cnx_teststate(conn, CC_STATUS_CLOSING))
    807840                                                CHECK_GNUTLS_DO( ret = gnutls_handshake(session),
    808841                                                        {
     
    815848                                case GNUTLS_E_AGAIN:
    816849                                case GNUTLS_E_INTERRUPTED:
    817                                         fd_cpu_flush_cache();
    818                                         if (!(conn->cc_status & CC_STATUS_CLOSING))
     850                                        if (!fd_cnx_teststate(conn, CC_STATUS_CLOSING))
    819851                                                goto again;
    820852                                        TRACE_DEBUG(FULL, "Connection is closing, so abord gnutls_record_recv now.");
     
    849881                        switch (ret) {
    850882                                case GNUTLS_E_REHANDSHAKE:
    851                                         fd_cpu_flush_cache();
    852                                         if (!(conn->cc_status & CC_STATUS_CLOSING))
     883                                        if (!fd_cnx_teststate(conn, CC_STATUS_CLOSING))
    853884                                                CHECK_GNUTLS_DO( ret = gnutls_handshake(session),
    854885                                                        {
     
    861892                                case GNUTLS_E_AGAIN:
    862893                                case GNUTLS_E_INTERRUPTED:
    863                                         fd_cpu_flush_cache();
    864                                         if (!(conn->cc_status & CC_STATUS_CLOSING))
     894                                        if (!fd_cnx_teststate(conn, CC_STATUS_CLOSING))
    865895                                                goto again;
    866896                                        TRACE_DEBUG(INFO, "Connection is closing, so abord gnutls_record_send now.");
     
    927957               
    928958                /* We have received a complete message, pass it to the daemon */
    929                 fd_cpu_flush_cache();
    930                 CHECK_FCT_DO( ret = fd_event_send( Target_Queue(conn), FDEVP_CNX_MSG_RECV, length, newmsg),
     959                CHECK_FCT_DO( ret = fd_event_send( fd_cnx_target_queue(conn), FDEVP_CNX_MSG_RECV, length, newmsg),
    931960                        {
    932961                                free(newmsg);
     
    956985        }
    957986       
    958         ASSERT( conn->cc_status & CC_STATUS_TLS );
    959         ASSERT( Target_Queue(conn) );
     987        ASSERT( fd_cnx_teststate(conn, CC_STATUS_TLS) );
     988        ASSERT( fd_cnx_target_queue(conn) );
    960989
    961990        /* The next function only returns when there is an error on the socket */       
     
    12151244{
    12161245        TRACE_ENTRY( "%p %d %p %p", conn, mode, priority, alt_creds);
    1217         CHECK_PARAMS( conn && (!(conn->cc_status & CC_STATUS_TLS)) && ( (mode == GNUTLS_CLIENT) || (mode == GNUTLS_SERVER) ) && (!conn->cc_loop) );
     1246        CHECK_PARAMS( conn && (!fd_cnx_teststate(conn, CC_STATUS_TLS)) && ( (mode == GNUTLS_CLIENT) || (mode == GNUTLS_SERVER) ) && (!conn->cc_loop) );
    12181247
    12191248        /* Save the mode */
     
    12481277
    12491278        /* Mark the connection as protected from here, so that the gnutls credentials will be freed */
    1250         fd_cpu_flush_cache();
    1251         conn->cc_status |= CC_STATUS_TLS;
    1252 
     1279        fd_cnx_addstate(conn, CC_STATUS_TLS);
     1280       
    12531281        /* Handshake master session */
    12541282        {
     
    12991327{
    13001328        TRACE_ENTRY("%p %p %p", conn, cert_list, cert_list_size);
    1301         CHECK_PARAMS( conn && (conn->cc_status & CC_STATUS_TLS) && cert_list && cert_list_size );
     1329        CHECK_PARAMS( conn && fd_cnx_teststate(conn, CC_STATUS_TLS) && cert_list && cert_list_size );
    13021330       
    13031331        /* This function only works for X.509 certificates. */
     
    13601388}
    13611389
     1390/* Where the events are sent */
     1391struct fifo * fd_cnx_target_queue(struct cnxctx * conn)
     1392{
     1393        struct fifo *q;
     1394        CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } );
     1395        q = conn->cc_alt ?: conn->cc_incoming;
     1396        CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } );
     1397        return q;
     1398}
     1399
    13621400/* Set an alternate FIFO list to send FDEVP_CNX_* events to */
    13631401int fd_cnx_recv_setaltfifo(struct cnxctx * conn, struct fifo * alt_fifo)
    13641402{
     1403        int ret;
    13651404        TRACE_ENTRY( "%p %p", conn, alt_fifo );
    13661405        CHECK_PARAMS( conn && alt_fifo && conn->cc_incoming );
    13671406       
    13681407        /* The magic function does it all */
    1369         CHECK_FCT( fd_fifo_move( conn->cc_incoming, alt_fifo, &conn->cc_alt ) );
    1370        
    1371         return 0;
     1408        CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } );
     1409        CHECK_FCT_DO( ret = fd_fifo_move( conn->cc_incoming, alt_fifo, &conn->cc_alt ), );
     1410        CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } );
     1411       
     1412        return ret;
    13721413}
    13731414
     
    13791420        TRACE_ENTRY("%p %p %zd", conn, buf, len);
    13801421        do {
    1381                 fd_cpu_flush_cache();
    1382                 if (conn->cc_status & CC_STATUS_TLS) {
     1422                if (fd_cnx_teststate(conn, CC_STATUS_TLS)) {
    13831423                        CHECK_GNUTLS_DO( ret = fd_tls_send_handle_error(conn, conn->cc_tls_para.session, buf + sent, len - sent),  );
    13841424                } else {
     
    13941434}
    13951435
    1396 /* Send a message -- this is synchronous -- and we assume it's never called by several threads at the same time, so we don't protect. */
     1436/* Send a message -- this is synchronous -- and we assume it's never called by several threads at the same time (on the same conn), so we don't protect. */
    13971437int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len, uint32_t flags)
    13981438{
    13991439        TRACE_ENTRY("%p %p %zd %x", conn, buf, len, flags);
    14001440       
    1401         CHECK_PARAMS(conn && (conn->cc_socket > 0) && (! (conn->cc_status & CC_STATUS_ERROR)) && buf && len);
    1402 
    1403         TRACE_DEBUG(FULL, "Sending %zdb %sdata on connection %s", len, (conn->cc_status & CC_STATUS_TLS) ? "TLS-protected ":"", conn->cc_id);
     1441        CHECK_PARAMS(conn && (conn->cc_socket > 0) && (! fd_cnx_teststate(conn, CC_STATUS_ERROR)) && buf && len);
     1442
     1443        TRACE_DEBUG(FULL, "Sending %zdb %sdata on connection %s", len, fd_cnx_teststate(conn, CC_STATUS_TLS) ? "TLS-protected ":"", conn->cc_id);
    14041444       
    14051445        switch (conn->cc_proto) {
     
    14101450#ifndef DISABLE_SCTP
    14111451                case IPPROTO_SCTP: {
    1412                         if (flags & FD_CNX_BROADCAST) {
    1413                                 /* Send the buffer over all other streams */
    1414                                 uint16_t str;
    1415                                 fd_cpu_flush_cache();
    1416                                 if (conn->cc_status & CC_STATUS_TLS) {
    1417                                         for ( str=1; str < conn->cc_sctp_para.pairs; str++) {
    1418                                                 ssize_t ret;
    1419                                                 size_t sent = 0;
    1420                                                 do {
    1421                                                         CHECK_GNUTLS_DO( ret = fd_tls_send_handle_error(conn, conn->cc_sctps_data.array[str].session, buf + sent, len - sent), );
    1422                                                         if (ret <= 0)
    1423                                                                 return ENOTCONN;
    1424 
    1425                                                         sent += ret;
    1426                                                 } while ( sent < len );
    1427                                         }
    1428                                 } else {
    1429                                         for ( str=1; str < conn->cc_sctp_para.str_out; str++) {
    1430                                                 CHECK_FCT_DO( fd_sctp_sendstr(conn->cc_socket, str, buf, len, &conn->cc_status), { fd_cnx_markerror(conn); return ENOTCONN; } );
    1431                                         }
    1432                                 }
    1433                                
    1434                                 /* Set the ORDERED flag also so that it is sent over stream 0 as well */
    1435                                 flags &= FD_CNX_ORDERED;
    1436                         }
    1437                        
    14381452                        if (flags & FD_CNX_ORDERED) {
    14391453                                /* We send over stream #0 */
     
    14441458                                int another_str = 0; /* do we send over stream #0 ? */
    14451459                               
    1446                                 if ((conn->cc_sctp_para.str_out > 1) && ((! (conn->cc_status & CC_STATUS_TLS)) || (conn->cc_sctp_para.pairs > 1)))  {
     1460                                if ((conn->cc_sctp_para.str_out > 1) && ((!fd_cnx_teststate(conn, CC_STATUS_TLS)) || (conn->cc_sctp_para.pairs > 1)))  {
    14471461                                        /* Update the id of the stream we will send this message over */
    14481462                                        conn->cc_sctp_para.next += 1;
    1449                                         conn->cc_sctp_para.next %= ((conn->cc_status & CC_STATUS_TLS) ? conn->cc_sctp_para.pairs : conn->cc_sctp_para.str_out);
     1463                                        conn->cc_sctp_para.next %= (fd_cnx_teststate(conn, CC_STATUS_TLS) ? conn->cc_sctp_para.pairs : conn->cc_sctp_para.str_out);
    14501464                                        another_str = (conn->cc_sctp_para.next ? 1 : 0);
    14511465                                }
     
    14541468                                        CHECK_FCT( send_simple(conn, buf, len) );
    14551469                                } else {
    1456                                         if (!(conn->cc_status & CC_STATUS_TLS)) {
    1457                                                 CHECK_FCT_DO( fd_sctp_sendstr(conn->cc_socket, conn->cc_sctp_para.next, buf, len, &conn->cc_status), { fd_cnx_markerror(conn); return ENOTCONN; } );
     1470                                        if (!fd_cnx_teststate(conn, CC_STATUS_TLS)) {
     1471                                                CHECK_FCT_DO( fd_sctp_sendstr(conn, conn->cc_sctp_para.next, buf, len), { fd_cnx_markerror(conn); return ENOTCONN; } );
    14581472                                        } else {
    14591473                                                /* push the record to the appropriate session */
     
    14961510        CHECK_PARAMS_DO(conn, return);
    14971511       
    1498         fd_cpu_flush_cache();
    1499         conn->cc_status |= CC_STATUS_CLOSING;
     1512        fd_cnx_addstate(conn, CC_STATUS_CLOSING);
    15001513       
    15011514        /* Initiate shutdown of the TLS session(s): call gnutls_bye(WR), then read until error */
    1502         if (conn->cc_status & CC_STATUS_TLS) {
     1515        if (fd_cnx_teststate(conn, CC_STATUS_TLS)) {
    15031516#ifndef DISABLE_SCTP
    15041517                if (conn->cc_sctp_para.pairs > 1) {
    1505                         if (! (conn->cc_status & CC_STATUS_ERROR )) {
     1518                        if (! fd_cnx_teststate(conn, CC_STATUS_ERROR )) {
    15061519                                /* Bye on master session */
    15071520                                CHECK_GNUTLS_DO( gnutls_bye(conn->cc_tls_para.session, GNUTLS_SHUT_WR), fd_cnx_markerror(conn) );
    15081521                        }
    15091522
    1510                         if (! (conn->cc_status & CC_STATUS_ERROR ) ) {
     1523                        if (! fd_cnx_teststate(conn, CC_STATUS_ERROR ) ) {
    15111524                                /* and other stream pairs */
    15121525                                fd_sctps_bye(conn);
    15131526                        }
    15141527
    1515                         if (! (conn->cc_status & CC_STATUS_ERROR ) ) {
     1528                        if (! fd_cnx_teststate(conn, CC_STATUS_ERROR ) ) {
    15161529                                /* Now wait for all decipher threads to terminate */
    15171530                                fd_sctps_waitthreadsterm(conn);
     
    15331546                } else {
    15341547#endif /* DISABLE_SCTP */
    1535                 /* We are not using the sctps wrapper layer */
    1536                         if (! (conn->cc_status & CC_STATUS_ERROR ) ) {
     1548                /* We are TLS, but not using the sctps wrapper layer */
     1549                        if (! fd_cnx_teststate(conn, CC_STATUS_ERROR ) ) {
    15371550                                /* Master session */
    15381551                                CHECK_GNUTLS_DO( gnutls_bye(conn->cc_tls_para.session, GNUTLS_SHUT_WR), fd_cnx_markerror(conn) );
    15391552                        }
    15401553
    1541                         if (! (conn->cc_status & CC_STATUS_ERROR ) ) {
     1554                        if (! fd_cnx_teststate(conn, CC_STATUS_ERROR ) ) {
    15421555                                /* In this case, just wait for thread rcvthr_tls_single to terminate */
    15431556                                if (conn->cc_rcvthr != (pthread_t)NULL) {
     
    15551568                                conn->cc_tls_para.session = NULL;
    15561569                        }
    1557                
    15581570#ifndef DISABLE_SCTP
    15591571                }
Note: See TracChangeset for help on using the changeset viewer.