Navigation


Changeset 21:bef197f6826f in freeDiameter


Ignore:
Timestamp:
Oct 8, 2009, 8:05:16 PM (15 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Backup before week-end, cnxctx and server in progress

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • doc/freediameter.conf.sample

    r20 r21  
    214214ConnectPeer = "jules.nautilus6.org" ;
    215215ConnectPeer = "aaa.nautilus6.org" { No_TLS; No_IP; No_TCP; SCTP_streams = 60; } ;
    216 TLS_Cred = "/etc/openssl-ca/clients/certs/fdtest.cert" , "/etc/openssl-ca/clients/privkeys/fdtest.key.pem";
     216TLS_Cred = "/etc/openssl-ca/clients/certs/test.cert" , "/etc/openssl-ca/clients/privkeys/test.key.pem";
    217217TLS_CA = "/etc/openssl-ca/public-www/cacert.pem";
    218218# TLS_CRL = "/etc/openssl-ca/public-www/crl.pem";
  • freeDiameter/cnxctx.c

    r20 r21  
    3636#include "fD.h"
    3737
    38 /* Initialize a connection context */
     38/* The connection context structure */
     39struct cnxctx {
     40        int             cc_socket;      /* The socket object of the connection -- <=0 if no socket is created */
     41       
     42        int             cc_proto;       /* IPPROTO_TCP or IPPROTO_SCTP */
     43        int             cc_tls;         /* Is TLS already started ? */
     44       
     45        struct fifo *   cc_events;      /* Events occuring on the connection */
     46        pthread_t       cc_mgr;         /* manager thread for the connection */
     47        struct fifo *   cc_incoming;    /* FIFO queue of messages received on the connection */
     48       
     49        uint16_t        cc_port;        /* Remote port of the connection, when we are client */
     50        struct fd_list  cc_ep_remote;   /* The remote address(es) of the connection */
     51        struct fd_list  cc_ep_local;    /* The local address(es) of the connection */
     52       
     53        /* If cc_proto == SCTP */
     54        struct  {
     55                int             str_out;/* Out streams */
     56                int             str_in; /* In streams */
     57                int             pairs;  /* max number of pairs ( = min(in, out)) */
     58                int             next;   /* # of stream the next message will be sent to */
     59        }               cc_sctp_para;
     60       
     61        /* If cc_tls == true */
     62        struct {
     63                int                              mode;          /* GNUTLS_CLIENT / GNUTLS_SERVER */
     64                gnutls_session_t                 session;       /* Session object (stream #0 in case of SCTP) */
     65        }               cc_tls_para;
     66       
     67        /* If both conditions */
     68        struct {
     69                gnutls_session_t                *res_sessions;  /* Sessions of other pairs of streams, resumed from the first */
     70                /* Buffers, threads, ... */
     71        }               cc_sctp_tls_para;
     72};
     73
     74
     75/* Initialize a context structure from a socket */
    3976struct cnxctx * fd_cnx_init(int sock, int proto)
    4077{
     
    66103}
    67104
    68 /* TLS handshake the connection */
     105/* Start receving messages in clear (no TLS) on the connection */
     106int fd_cnx_start_clear(struct cnxctx * conn)
     107{
     108       
     109        TODO("...");
     110        return ENOTSUP;
     111}
     112
     113/* TLS handshake a connection; no need to have called start_clear before. Reception is active if handhsake is successful */
    69114int fd_cnx_handshake(struct cnxctx * conn, int mode)
    70115{
     
    142187        return 0;
    143188}
     189
     190/* Retrieve TLS credentials of the remote peer, after handshake */
     191int fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsigned int *cert_list_size)
     192{
     193       
     194        TODO("...");
     195        return ENOTSUP;
     196}
     197
     198/* Get the list of endpoints (IP addresses) of the remote peer on this object */
     199int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * senti)
     200{
     201       
     202        TODO("...");
     203        return ENOTSUP;
     204}
     205
     206
     207/* Get a string describing the remote peer address (ip address or fqdn) */
     208char * fd_cnx_getremoteid(struct cnxctx * conn)
     209{
     210       
     211        TODO("...");
     212        return NULL;
     213}
     214
     215
     216/* Receive next message. if timeout is not NULL, wait only until timeout */
     217int fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len)
     218{
     219       
     220        TODO("...");
     221        return ENOTSUP;
     222}
     223
     224
     225/* Send a message */
     226int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len)
     227{
     228       
     229        TODO("...");
     230        return ENOTSUP;
     231}
     232
     233
     234/* Destroy a conn structure, and shutdown the socket */
     235void fd_cnx_destroy(struct cnxctx * conn)
     236{
     237       
     238        TODO("...");
     239        return;
     240}
     241
     242
     243
     244
  • freeDiameter/fD.h

    r20 r21  
    173173};
    174174
    175 /* The connection context structure */
    176 struct cnxctx {
    177         int             cc_socket;      /* The socket object of the connection -- <=0 if no socket is created */
    178        
    179         struct fifo   **cc_events;      /* Location of the events list to send connection events */
    180        
    181         int             cc_proto;       /* IPPROTO_TCP or IPPROTO_SCTP */
    182         int             cc_tls;         /* Is TLS already started ? */
    183        
    184         uint16_t        cc_port;        /* Remote port of the connection, when we are client */
    185         struct fd_list  cc_ep_remote;   /* The remote address(es) of the connection */
    186         struct fd_list  cc_ep_local;    /* The local address(es) of the connection */
    187        
    188         /* If cc_proto == SCTP */
    189         struct  {
    190                 int             str_out;/* Out streams */
    191                 int             str_in; /* In streams */
    192                 int             pairs;  /* max number of pairs ( = min(in, out)) */
    193                 int             next;   /* # of stream the next message will be sent to */
    194         }               cc_sctp_para;
    195        
    196         /* If cc_tls == true */
    197         struct {
    198                 int                              mode;          /* GNUTLS_CLIENT / GNUTLS_SERVER */
    199                 gnutls_session_t                 session;       /* Session object (stream #0 in case of SCTP) */
    200         }               cc_tls_para;
    201        
    202         /* If both conditions */
    203         struct {
    204                 gnutls_session_t                *res_sessions;  /* Sessions of other pairs of streams, resumed from the first */
    205                 /* Buffers, threads, ... */
    206         }               cc_sctp_tls_para;
    207 };
    208175
    209176/* Functions */
     
    233200/* Connection contexts */
    234201struct cnxctx * fd_cnx_init(int sock, int proto);
     202int fd_cnx_start_clear(struct cnxctx * conn);
    235203int fd_cnx_handshake(struct cnxctx * conn, int mode);
     204int fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsigned int *cert_list_size);
     205int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * senti);
     206char * fd_cnx_getremoteid(struct cnxctx * conn);
     207int fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len);
     208int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len);
     209void fd_cnx_destroy(struct cnxctx * conn);
    236210
    237211/* SCTP */
  • freeDiameter/server.c

    r20 r21  
    6262struct client {
    6363        struct fd_list   chain; /* link in the server's list of clients */
    64        
    6564        struct cnxctx   *conn;  /* Parameters of the connection; sends its events to the ev fifo bellow */
    66        
    6765        struct timespec  ts;    /* Delay for receiving CER: INCNX_TIMEOUT */
    68         struct fifo     *ev;    /* Events of the connection -- allowed: TIMEOUT, ERROR (cnx, tls), MSG_RCV (CER, other=>error) */
    69        
    7066        pthread_t        cli_thr; /* connection state machine (simplified PSM) */
    7167};
     
    8076
    8177
     78static void * client_simple_psm(void * arg)
     79{
     80        struct client * c = arg;
     81        struct server * s = NULL;
     82       
     83        TRACE_ENTRY("%p", c);
     84       
     85        CHECK_PARAMS_DO(c && c->conn && c->chain.head, goto fatal_error );
     86       
     87        s = c->chain.head->o;
     88       
     89        /* Name the current thread */
     90        {
     91                char addr[128];
     92                snprintf(addr, sizeof(addr), "Srv %d/Cli %s", s->socket, fd_cnx_getremoteid(c->conn));
     93                fd_log_threadname ( addr );
     94        }
     95       
     96        /* Set the timeout to receive the first message */
     97        CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &c->ts), goto fatal_error );
     98        c->ts.tv_sec += INCNX_TIMEOUT;
     99       
     100        TODO("receive message until c->ts");
     101       
     102        TODO("Timeout => close");
     103        TODO("Message != CER => close");
     104        TODO("Message == CER : ");
     105        TODO("Search matching peer");
     106        TODO("...");
     107       
     108        /* The end: we have freed the client structure already */
     109        TODO("Unlink the client structure");
     110        TODO(" pthread_detach(c->cli_thr); ");
     111        TODO(" free(c); ");
     112        return NULL;
     113       
     114fatal_error:    /* This has effect to terminate the daemon */
     115        CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, NULL), );
     116        return NULL;
     117}
     118
    82119/* This thread is called when a new client had just connected */
    83120static void * handle_client_fast(void * arg)
     
    90127        {
    91128                char addr[128];
    92                 int offset = snprintf(addr, sizeof(addr), "Srv %d/Cli %d : ", cf->serv->socket, cf->sock);
     129                int offset = snprintf(addr, sizeof(addr), "Srv %d/CliFast %d : ", cf->serv->socket, cf->sock);
    93130                int rc = getnameinfo((sSA *)&cf->ss, sizeof(sSS), addr + offset, sizeof(addr) - offset, NULL, 0, 0);
    94131                if (rc)
    95132                        memcpy(addr + offset, gai_strerror(rc), sizeof(addr) - offset);
    96133               
     134                fd_log_threadname ( addr );
     135       
    97136                if (TRACE_BOOL(INFO)) {
    98137                        fd_log_debug( "New connection %s, sock %d, from '%s'\n", cf->serv->serv_name, cf->sock, addr + offset);
    99138                }
    100        
    101                 fd_log_threadname ( addr );
    102139        }
    103140       
    104141        /* Create a client structure */
    105         CHECK_MALLOC_DO( c = malloc(sizeof(struct client)), goto early_error );
     142        CHECK_MALLOC_DO( c = malloc(sizeof(struct client)), goto fatal_error );
    106143        memset(c, 0, sizeof(struct client));
    107144        fd_list_init(&c->chain, c);
    108         c->cli_thr = pthread_self();
    109145       
    110146        /* Create the connection context */
    111         CHECK_MALLOC_DO( c->conn = fd_cnx_init(cf->sock, cf->serv->proto), goto early_error );
     147        CHECK_MALLOC_DO( c->conn = fd_cnx_init(cf->sock, cf->serv->proto), goto fatal_error );
    112148       
    113149        /* In case we are a secure server, handshake now */
    114150        if (cf->serv->secur) {
    115                
    116                 TODO("Continue");
    117         }
     151                CHECK_FCT_DO( fd_cnx_handshake(c->conn, GNUTLS_CLIENT), goto cleanup );
     152        }
     153       
    118154       
    119155        /* Save the client in the list */
    120         CHECK_POSIX_DO( pthread_mutex_lock( &cf->serv->clients_mtx ), goto early_error );
     156        CHECK_POSIX_DO( pthread_mutex_lock( &cf->serv->clients_mtx ), goto fatal_error );
    121157        fd_list_insert_before(&cf->serv->clients, &c->chain);
    122         CHECK_POSIX_DO( pthread_mutex_unlock( &cf->serv->clients_mtx ), goto error );
    123        
    124        
    125        
    126        
    127 early_error:
    128         TRACE_DEBUG(INFO, "Thread is detaching to die");
    129         pthread_detach(pthread_self());
    130         shutdown(cf->sock, SHUT_RDWR);
     158        CHECK_POSIX_DO( pthread_mutex_unlock( &cf->serv->clients_mtx ), goto fatal_error );
     159       
     160        /* Start the client thread */
     161        CHECK_POSIX_DO( pthread_create( &c->cli_thr, NULL, client_simple_psm, c ), goto fatal_error );
     162       
     163        /* We're done here */
     164        free(cf);
     165        return NULL;
     166       
     167cleanup:        /* Clean all objects and return (minor error on the connection)*/
     168        if (c && c->conn) {
     169                TODO( "Free the c->conn object & gnutls data" );
     170        }
     171       
     172        return NULL;   
     173       
     174fatal_error:    /* This has effect to terminate the daemon */
     175        CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, NULL), );
    131176        free(cf);
    132177        free(c);
    133 error: 
    134         TRACE_DEBUG(INFO, "Thread is terminating");
    135         CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, NULL), );
    136178        return NULL;
    137179}
     
    142184        struct server *sv = (struct server *)arg;
    143185        struct cli_fast cf;
     186        pthread_attr_t  attr;
    144187       
    145188        CHECK_PARAMS_DO(sv, goto error);
     
    150193        cf.serv = sv;
    151194       
     195        CHECK_POSIX_DO( pthread_attr_init(&attr), goto error );
     196        CHECK_POSIX_DO( pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED), goto error );
    152197       
    153198        /* Accept incoming connections */
     
    171216               
    172217                /* Create the thread to handle the new incoming connection */
    173                 CHECK_POSIX_DO( pthread_create( &thr /* we don't use it, but NULL is not standard */, NULL, handle_client_fast, ncf), goto error );
     218                CHECK_POSIX_DO( pthread_create( &thr, &attr, handle_client_fast, ncf), goto error );
    174219               
    175220        } while (1);
     
    231276                                ((sv->serv_status == 2) ? "Thread terminated" :
    232277                                                          "Thread status unknown")));
    233                 /* Dump the endpoints ? */
    234                 /* Dump the client list ? */
     278                /* Dump the client list */
     279                TODO("Dump client list");
    235280        }
    236281}
     
    251296                CHECK_FCT( fd_sctp_create_bind_server( &socket, fd_g_config->cnf_port ) );
    252297                CHECK_MALLOC( sv = new_serv(IPPROTO_SCTP, 0, socket) );
    253                
    254                
    255                
     298                TODO("Link");
     299                TODO("Start thread");
     300               
     301                /* Create the server on secure port */
    256302               
    257303#endif /* DISABLE_SCTP */
     
    261307        if (!fd_g_config->cnf_flags.no_tcp) {
    262308               
    263                
     309                if (FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints)) {
     310                        /* if not no_IP : create server for 0.0.0.0 */
     311                        /* if not no_IP6 : create server for :: */
     312                } else {
     313                        /* Create all endpoints -- check flags */
     314                }
    264315        }
    265316       
     
    270321void fd_servers_stop()
    271322{
    272        
    273 }
     323        /* Loop on all servers */
     324                /* cancel thread */
     325                /* shutdown the socket */
     326                /* empty list of clients (stop them) */
     327}
  • libfreeDiameter/fifo.c

    r14 r21  
    136136}
    137137
    138 /* Delete a queue. It must be unused. */
     138/* Delete a queue. It must be empty. */
    139139int fd_fifo_del ( struct fifo  ** queue )
    140140{
    141141        struct fifo * q;
     142        int loops = 0;
    142143       
    143144        TRACE_ENTRY( "%p", queue );
     
    149150        CHECK_POSIX(  pthread_mutex_lock( &q->mtx )  );
    150151       
    151         if ((q->count != 0) || (q->thrs != 0) || (q->data != NULL)) {
    152                 TRACE_DEBUG(INFO, "The queue cannot be destroyed (%d, %d, %p)", q->count, q->thrs, q->data);
     152        /* Ok, now invalidate the queue */
     153        q->eyec = 0xdead;
     154       
     155        if ((q->count != 0) || (q->data != NULL)) {
     156                TRACE_DEBUG(INFO, "The queue cannot be destroyed (%d, %p)", q->count, q->data);
    153157                CHECK_POSIX_DO(  pthread_mutex_unlock( &q->mtx ), /* no fallback */  );
    154158                return EINVAL;
    155159        }
    156160       
     161        while (q->thrs) {
     162                CHECK_POSIX(  pthread_cond_signal(&q->cond)  );
     163                CHECK_POSIX(  pthread_mutex_unlock( &q->mtx ));
     164                pthread_yield();
     165                CHECK_POSIX(  pthread_mutex_lock( &q->mtx )  );
     166                ASSERT( ++loops < 10 ); /* detect infinite loops */
     167        }
     168       
    157169        /* sanity check */
    158170        ASSERT(FD_IS_LIST_EMPTY(&q->list));
    159        
    160         /* Ok, now invalidate the queue */
    161         q->eyec = 0xdead;
    162171       
    163172        /* And destroy it */
     
    379388awaken:
    380389        /* Check queue status */
     390        if (!CHECK_FIFO( queue )) {
     391                /* The queue is being destroyed */
     392                CHECK_POSIX(  pthread_mutex_unlock( &queue->mtx )  );
     393                TRACE_DEBUG(FULL, "The queue is being destroyed -> EPIPE");
     394                return EPIPE;
     395        }
     396               
    381397        if (queue->count > 0) {
    382398                /* There are items in the queue, so pick the first one */
Note: See TracChangeset for help on using the changeset viewer.