Navigation


Changeset 22:0b3b46da2c12 in freeDiameter


Ignore:
Timestamp:
Oct 19, 2009, 6:43:09 PM (14 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Progress on server code

Files:
1 added
15 edited

Legend:

Unmodified
Added
Removed
  • doc/freediameter.conf.sample

    r21 r22  
    184184#  No_TLS;       # assume transparent security instead of TLS
    185185#  Port = 3868;  # The port to connect to
    186 #  SCTP_streams = 30;
    187186#  TcTimer = 30;
    188187#  TwTimer = 30;
    189188#  ConnectTo = "202.249.37.5";
    190189#  ConnectTo = "2001:200:903:2::202:1";
     190#  TLS_Prio = "NORMAL";
    191191# Examples:
    192192#ConnectPeer = "aaa.wide.ad.jp";
     
    201201SecPort = 3867;
    202202TLS_old_method;
    203 No_IP;
     203No_SCTP;
    204204Prefer_TCP;
    205205SCTP_streams = 50;
    206 ListenOn = "202.249.37.5";
    207 ListenOn = "2001:200:903:2::202:1";
     206#ListenOn = "202.249.37.5";
     207#ListenOn = "2001:200:903:2::202:1";
    208208TcTimer = 60;
    209209TwTimer = 6;
     
    213213LoadExtension = "extensions/dict_eap.fdx";
    214214ConnectPeer = "jules.nautilus6.org" ;
    215 ConnectPeer = "aaa.nautilus6.org" { No_TLS; No_IP; No_TCP; SCTP_streams = 60; } ;
     215ConnectPeer = "aaa.nautilus6.org" { No_TLS; No_IP; } ;
    216216TLS_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";
  • freeDiameter/CMakeLists.txt

    r20 r22  
    2121        p_psm.c
    2222        server.c
     23        tcp.c
    2324        )
    2425
  • freeDiameter/cnxctx.c

    r21 r22  
    3636#include "fD.h"
    3737
     38/* Connections contexts (cnxctx) in freeDiameter are wrappers around the sockets and TLS operations .
     39 * They are used to hide the details of the processing to the higher layers of the daemon.
     40 * They are always oriented on connections (TCP or SCTP), connectionless modes (UDP or SCTP) are not supported.
     41 */
     42
     43/* Note: this file could be moved to libfreeDiameter instead, but since it uses gnuTLS we prefer to keep it in the daemon */
     44
     45/* Lifetime of a cnxctx object:
     46 * 1) Creation
     47 *    a) a server socket:
     48 *       - create the object with fd_cnx_serv_tcp or fd_cnx_serv_sctp
     49 *       - start listening incoming connections: fd_cnx_serv_listen
     50 *       - accept new clients with fd_cnx_serv_accept.
     51 *    b) a client socket:
     52 *       - connect to a remote server with fd_cnx_cli_connect
     53 *
     54 * 2) Initialization
     55 *    - if TLS is started first, call fd_cnx_handshake
     56 *    - otherwise to receive clear messages, call fd_cnx_start_clear. fd_cnx_handshake can be called later.
     57 *
     58 * 3) Usage
     59 *    - fd_cnx_receive, fd_cnx_send : exchange messages on this connection (send is synchronous, receive is not).
     60 *    - fd_cnx_recv_setaltfifo : when a message is received, the event is sent to an external fifo list. fd_cnx_receive does not work when the alt_fifo is set.
     61 *    - fd_cnx_getid : retrieve a descriptive string for the connection (for debug)
     62 *    - fd_cnx_getremoteid : identification of the remote peer (IP address or fqdn)
     63 *    - fd_cnx_getcred : get the remote peer TLS credentials, after handshake
     64 *    - fd_cnx_getendpoints : get the endpoints (IP) of the connection
     65 *
     66 * 4) End
     67 *    - fd_cnx_destroy
     68 */
     69
    3870/* The connection context structure */
    3971struct cnxctx {
     72        char            cc_id[60];      /* The name of this connection */
     73        char            cc_remid[60];   /* Id of remote peer */
     74
    4075        int             cc_socket;      /* The socket object of the connection -- <=0 if no socket is created */
    41        
     76
    4277        int             cc_proto;       /* IPPROTO_TCP or IPPROTO_SCTP */
    4378        int             cc_tls;         /* Is TLS already started ? */
    44        
     79
    4580        struct fifo *   cc_events;      /* Events occuring on the connection */
    4681        pthread_t       cc_mgr;         /* manager thread for the connection */
    4782        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        
     83        struct fifo *   cc_alt;         /* alternate fifo to send FDEVP_CNX_MSG_RECV events to. */
     84
    5385        /* If cc_proto == SCTP */
    5486        struct  {
     
    5890                int             next;   /* # of stream the next message will be sent to */
    5991        }               cc_sctp_para;
    60        
     92
    6193        /* If cc_tls == true */
    6294        struct {
     
    6496                gnutls_session_t                 session;       /* Session object (stream #0 in case of SCTP) */
    6597        }               cc_tls_para;
    66        
     98
    6799        /* If both conditions */
    68100        struct {
     
    73105
    74106
    75 /* Initialize a context structure from a socket */
    76 struct cnxctx * fd_cnx_init(int sock, int proto)
     107/* Initialize a context structure */
     108static struct cnxctx * fd_cnx_init(int full)
    77109{
    78110        struct cnxctx * conn = NULL;
    79        
    80         TRACE_ENTRY("%d %d", sock, proto);
    81         CHECK_PARAMS_DO( (proto == IPPROTO_TCP) || (proto == IPPROTO_SCTP), return NULL);
    82        
     111
     112        TRACE_ENTRY("%d", full);
     113
    83114        CHECK_MALLOC_DO( conn = malloc(sizeof(struct cnxctx)), return NULL );
    84115        memset(conn, 0, sizeof(struct cnxctx));
    85        
    86         conn->cc_socket = sock;
    87         conn->cc_proto  = proto;
    88        
    89         fd_list_init(&conn->cc_ep_remote, conn);
    90         fd_list_init(&conn->cc_ep_local, conn);
    91        
    92         if (proto == IPPROTO_SCTP) {
     116
     117        if (full) {
     118                CHECK_FCT_DO( fd_fifo_new ( &conn->cc_events ), return NULL );
     119                CHECK_FCT_DO( fd_fifo_new ( &conn->cc_incoming ), return NULL );
     120        }
     121
     122        return conn;
     123}
     124
     125/* Create and bind a server socket to the given endpoint and port */
     126struct cnxctx * fd_cnx_serv_tcp(uint16_t port, int family, struct fd_endpoint * ep)
     127{
     128        struct cnxctx * cnx = NULL;
     129        sSS dummy;
     130        sSA * sa = (sSA *) &dummy;
     131
     132        TRACE_ENTRY("%hu %d %p", port, family, ep);
     133
     134        CHECK_PARAMS_DO( port, return NULL );
     135        CHECK_PARAMS_DO( ep || family, return NULL );
     136        CHECK_PARAMS_DO( (! family) || (family == AF_INET) || (family == AF_INET6), return NULL );
     137        CHECK_PARAMS_DO( (! ep) || (!family) || (ep->ss.ss_family == family), return NULL );
     138
     139        /* The connection object */
     140        CHECK_MALLOC_DO( cnx = fd_cnx_init(0), return NULL );
     141
     142        /* Prepare the socket address information */
     143        if (ep) {
     144                memcpy(sa, &ep->ss, sizeof(sSS));
     145        } else {
     146                memset(&dummy, 0, sizeof(dummy));
     147                sa->sa_family = family;
     148        }
     149        if (sa->sa_family == AF_INET) {
     150                ((sSA4 *)sa)->sin_port = htons(port);
     151        } else {
     152                ((sSA6 *)sa)->sin6_port = htons(port);
     153        }
     154
     155        /* Create the socket */
     156        CHECK_FCT_DO( fd_tcp_create_bind_server( &cnx->cc_socket, sa, sizeof(sSS) ), goto error );
     157
     158        /* Generate the name for the connection object */
     159        {
     160                char addrbuf[INET6_ADDRSTRLEN];
     161                int  rc;
     162                rc = getnameinfo(sa, sizeof(sSS), addrbuf, sizeof(addrbuf), NULL, 0, NI_NUMERICHOST);
     163                if (rc)
     164                        snprintf(addrbuf, sizeof(addrbuf), "[err:%s]", gai_strerror(rc));
     165                snprintf(cnx->cc_id, sizeof(cnx->cc_id), "Srv TCP [%s]:%hu (%d)", addrbuf, port, cnx->cc_socket);
     166        }
     167
     168        cnx->cc_proto = IPPROTO_TCP;
     169
     170        return cnx;
     171
     172error:
     173        fd_cnx_destroy(cnx);
     174        return NULL;
     175}
    93176#ifndef DISABLE_SCTP
    94                 CHECK_FCT_DO( fd_sctp_get_str_info( sock, &conn->cc_sctp_para.str_in, &conn->cc_sctp_para.str_out ),
    95                                 { free(conn); return NULL; } );
    96                 conn->cc_sctp_para.pairs = (conn->cc_sctp_para.str_out < conn->cc_sctp_para.str_in) ? conn->cc_sctp_para.str_out : conn->cc_sctp_para.str_in;
    97 #else /* DISABLE_SCTP */
    98                 ASSERT(0);
     177struct cnxctx * fd_cnx_serv_sctp(uint16_t port, struct fd_list * ep_list)
     178{
     179        struct cnxctx * cnx = NULL;
     180        sSS dummy;
     181        sSA * sa = (sSA *) &dummy;
     182
     183        TRACE_ENTRY("%hu %p", port, ep_list);
     184
     185        CHECK_PARAMS_DO( port, return NULL );
     186
     187        /* The connection object */
     188        CHECK_MALLOC_DO( cnx = fd_cnx_init(0), return NULL );
     189
     190        /* Create the socket */
     191        CHECK_FCT_DO( fd_sctp_create_bind_server( &cnx->cc_socket, ep_list, port ), goto error );
     192
     193        /* Generate the name for the connection object */
     194        snprintf(cnx->cc_id, sizeof(cnx->cc_id), "Srv SCTP :%hu (%d)", port, cnx->cc_socket);
     195
     196        cnx->cc_proto = IPPROTO_SCTP;
     197
     198        return cnx;
     199
     200error:
     201        fd_cnx_destroy(cnx);
     202        return NULL;
     203}
    99204#endif /* DISABLE_SCTP */
    100         }
    101        
    102         return conn;
     205
     206/* Allow clients to connect on the server socket */
     207int fd_cnx_serv_listen(struct cnxctx * conn)
     208{
     209        CHECK_PARAMS( conn );
     210
     211        switch (conn->cc_proto) {
     212                case IPPROTO_TCP:
     213                        CHECK_FCT(fd_tcp_listen(conn->cc_socket));
     214                        break;
     215
     216                case IPPROTO_SCTP:
     217                        CHECK_FCT(fd_sctp_listen(conn->cc_socket));
     218                        break;
     219
     220                default:
     221                        CHECK_PARAMS(0);
     222        }
     223
     224        return 0;
     225}
     226
     227/* Accept a client (blocking until a new client connects) -- cancelable */
     228struct cnxctx * fd_cnx_serv_accept(struct cnxctx * serv)
     229{
     230        struct cnxctx * cli = NULL;
     231        sSS ss;
     232        socklen_t ss_len = sizeof(ss);
     233        int cli_sock = 0;
     234        struct fd_endpoint * ep;
     235
     236        TRACE_ENTRY("%p", serv);
     237        CHECK_PARAMS_DO(serv, return NULL);
     238       
     239        CHECK_SYS_DO( cli_sock = accept(serv->cc_socket, (sSA *)&ss, &ss_len), return NULL );
     240       
     241        if (TRACE_BOOL(INFO)) {
     242                fd_log_debug("%s - new client [", fd_cnx_getid(serv));
     243                sSA_DUMP_NODE( &ss, AI_NUMERICHOST );
     244                fd_log_debug("] connected.\n");
     245        }
     246       
     247        CHECK_MALLOC_DO( cli = fd_cnx_init(1), { shutdown(cli_sock, SHUT_RDWR); return NULL; } );
     248        cli->cc_socket = cli_sock;
     249        cli->cc_proto = serv->cc_proto;
     250       
     251        /* Generate the name for the connection object */
     252        {
     253                char addrbuf[INET6_ADDRSTRLEN];
     254                char portbuf[10];
     255                int  rc;
     256               
     257                /* Numeric values for debug */
     258                rc = getnameinfo((sSA *)&ss, sizeof(sSS), addrbuf, sizeof(addrbuf), portbuf, sizeof(portbuf), NI_NUMERICHOST | NI_NUMERICSERV);
     259                if (rc)
     260                        snprintf(addrbuf, sizeof(addrbuf), "[err:%s]", gai_strerror(rc));
     261               
     262                snprintf(cli->cc_id, sizeof(cli->cc_id), "Client %s [%s]:%s (%d) / serv (%d)",
     263                                IPPROTO_NAME(cli->cc_proto),
     264                                addrbuf, portbuf,
     265                                cli->cc_socket, serv->cc_socket);
     266               
     267                /* Textual value for log messages */
     268                rc = getnameinfo((sSA *)&ss, sizeof(sSS), cli->cc_remid, sizeof(cli->cc_remid), NULL, 0, NI_NUMERICHOST);
     269                if (rc)
     270                        snprintf(cli->cc_remid, sizeof(cli->cc_remid), "[err:%s]", gai_strerror(rc));
     271        }
     272
     273        /* SCTP-specific handlings */
     274#ifndef DISABLE_SCTP
     275        if (cli->cc_proto == IPPROTO_SCTP) {
     276                /* Retrieve the number of streams */
     277                CHECK_FCT_DO( fd_sctp_get_str_info( cli->cc_socket, &cli->cc_sctp_para.str_in, &cli->cc_sctp_para.str_out ), goto error );
     278                if (cli->cc_sctp_para.str_out > cli->cc_sctp_para.str_in)
     279                        cli->cc_sctp_para.pairs = cli->cc_sctp_para.str_out;
     280                else
     281                        cli->cc_sctp_para.pairs = cli->cc_sctp_para.str_in;
     282        }
     283#endif /* DISABLE_SCTP */
     284
     285        return cli;
     286error:
     287        fd_cnx_destroy(cli);
     288        return NULL;
     289}
     290
     291/* Client side: connect to a remote server */
     292struct cnxctx * fd_cnx_cli_connect(int proto, const sSA * sa,  socklen_t addrlen)
     293{
     294
     295        TODO("...");
     296        return NULL;
     297}
     298
     299/* Return a string describing the connection, for debug */
     300char * fd_cnx_getid(struct cnxctx * conn)
     301{
     302        CHECK_PARAMS_DO( conn, return "" );
     303        return conn->cc_id;
    103304}
    104305
     
    106307int fd_cnx_start_clear(struct cnxctx * conn)
    107308{
    108        
     309
    109310        TODO("...");
    110311        return ENOTSUP;
     
    112313
    113314/* TLS handshake a connection; no need to have called start_clear before. Reception is active if handhsake is successful */
    114 int fd_cnx_handshake(struct cnxctx * conn, int mode)
     315int fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority)
    115316{
    116317        TRACE_ENTRY( "%p %d", conn, mode);
    117318        CHECK_PARAMS( conn && ( (mode == GNUTLS_CLIENT) || (mode == GNUTLS_SERVER) ) );
    118        
     319
    119320        /* Save the mode */
    120321        conn->cc_tls_para.mode = mode;
    121        
     322
    122323        /* Create the master session context */
    123324        CHECK_GNUTLS_DO( gnutls_init (&conn->cc_tls_para.session, mode), return ENOMEM );
    124        
     325
    125326        /* Set the algorithm suite */
     327        TODO("Use overwrite priority if non NULL");
    126328        CHECK_GNUTLS_DO( gnutls_priority_set( conn->cc_tls_para.session, fd_g_config->cnf_sec_data.prio_cache ), return EINVAL );
    127        
     329
    128330        /* Set the credentials of this side of the connection */
    129331        CHECK_GNUTLS_DO( gnutls_credentials_set (conn->cc_tls_para.session, GNUTLS_CRD_CERTIFICATE, fd_g_config->cnf_sec_data.credentials), return EINVAL );
    130        
     332
    131333        /* Request the remote credentials as well */
    132334        if (mode == GNUTLS_SERVER) {
     
    146348#endif /* DISABLE_SCTP */
    147349        }
    148        
     350
    149351        /* Handshake master session */
    150352        {
     
    153355                        {
    154356                                if (TRACE_BOOL(INFO)) {
    155                                         fd_log_debug("TLS Handshake failed on socket %d : %s\n", conn->cc_socket, gnutls_strerror(ret));
     357                                        fd_log_debug("TLS Handshake failed on socket %d (%s) : %s\n", conn->cc_socket, conn->cc_id, gnutls_strerror(ret));
    156358                                }
    157359                                return EINVAL;
    158360                        } );
    159                
     361
    160362                /* Now verify the remote credentials are valid -- only simple test here */
    161363                CHECK_GNUTLS_DO( gnutls_certificate_verify_peers2 (conn->cc_tls_para.session, &ret), return EINVAL );
    162364                if (ret) {
    163365                        if (TRACE_BOOL(INFO)) {
    164                                 fd_log_debug("TLS: Remote certificate invalid on socket %d :\n", conn->cc_socket);
     366                                fd_log_debug("TLS: Remote certificate invalid on socket %d (%s) :\n", conn->cc_socket, conn->cc_id);
    165367                                if (ret & GNUTLS_CERT_INVALID)
    166368                                        fd_log_debug(" - The certificate is not trusted (unknown CA?)\n");
     
    177379                }
    178380        }
    179        
     381
    180382        /* Other sessions in case of multi-stream SCTP are resumed from the master */
    181383        if ((conn->cc_proto == IPPROTO_SCTP) && (conn->cc_sctp_para.pairs > 0)) {
     
    184386#endif /* DISABLE_SCTP */
    185387        }
    186        
     388
     389        TODO("Start the connection state machine thread");
     390
    187391        return 0;
    188392}
     
    191395int fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsigned int *cert_list_size)
    192396{
    193        
     397
    194398        TODO("...");
    195399        return ENOTSUP;
    196400}
    197401
    198 /* Get the list of endpoints (IP addresses) of the remote peer on this object */
    199 int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * senti)
    200 {
    201        
     402/* Get the list of endpoints (IP addresses) of the local and remote peers on this conenction */
     403int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_list * remote)
     404{
     405        TRACE_ENTRY("%p %p %p", conn, local, remote);
     406        CHECK_PARAMS(conn);
     407       
     408        if (local) {
     409                /* Retrieve the local endpoint(s) of the connection */
     410                TODO("TCP : getsockname");
     411                TODO("SCTP: sctp_getladdrs / _sctp_getboundaddrs (waaad)");
     412        }
     413       
     414        if (remote) {
     415                /* Retrieve the peer endpoint(s) of the connection */
     416                TODO("TCP : getpeername");
     417                TODO("SCTP: sctp_getpaddrs");
     418               
     419        }
     420
     421        return ENOTSUP;
     422}
     423
     424
     425/* Get a string describing the remote peer address (ip address or fqdn) */
     426char * fd_cnx_getremoteid(struct cnxctx * conn)
     427{
     428        CHECK_PARAMS_DO( conn, return "" );
     429        return conn->cc_remid;
     430}
     431
     432
     433/* Receive next message. if timeout is not NULL, wait only until timeout */
     434int fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len)
     435{
     436
    202437        TODO("...");
    203438        return ENOTSUP;
    204439}
    205440
    206 
    207 /* Get a string describing the remote peer address (ip address or fqdn) */
    208 char * 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 */
    217 int fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len)
    218 {
    219        
     441/* Set / reset alternate FIFO list to send FDEVP_CNX_MSG_RECV to when message is received */
     442int fd_cnx_recv_setaltfifo(struct cnxctx * conn, struct fifo * alt_fifo)
     443{
     444        TRACE_ENTRY( "%p %p", conn, alt_fifo );
     445        CHECK_PARAMS( conn );
     446       
     447        /* Let's cross fingers that there is no race condition here... */
     448        conn->cc_alt = alt_fifo;
     449       
     450        return 0;
     451}
     452
     453/* Send a message */
     454int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len)
     455{
     456
    220457        TODO("...");
    221458        return ENOTSUP;
     
    223460
    224461
    225 /* Send a message */
    226 int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len)
    227 {
    228        
    229         TODO("...");
    230         return ENOTSUP;
    231 }
    232 
    233 
    234462/* Destroy a conn structure, and shutdown the socket */
    235463void fd_cnx_destroy(struct cnxctx * conn)
    236464{
    237        
    238         TODO("...");
     465        TRACE_ENTRY("%p", conn);
     466       
     467        CHECK_PARAMS_DO(conn, return);
     468
     469        TODO("End TLS session(s) if started");
     470       
     471        TODO("Stop manager thread if running");
     472       
     473        /* Shut the connection down */
     474        if (conn->cc_socket > 0) {
     475                shutdown(conn->cc_socket, SHUT_RDWR);
     476        }
     477       
     478        TODO("Empty FIFO queues");
     479       
     480        /* Destroy FIFO lists */
     481        if (conn->cc_events)
     482                CHECK_FCT_DO( fd_fifo_del ( &conn->cc_events ), /* continue */ );
     483        if (conn->cc_incoming)
     484                CHECK_FCT_DO( fd_fifo_del ( &conn->cc_incoming ), /* continue */ );
     485       
     486        /* Free the object */
     487        free(conn);
     488       
     489        /* Done! */
    239490        return;
    240491}
  • freeDiameter/config.c

    r20 r22  
    229229        }
    230230       
     231        /* Validate local endpoints */
     232        if ((!FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints)) && (fd_g_config->cnf_flags.no_ip4 || fd_g_config->cnf_flags.no_ip6)) {
     233                struct fd_list * li;
     234                for ( li = fd_g_config->cnf_endpoints.next; li != &fd_g_config->cnf_endpoints; li = li->next) {
     235                        struct fd_endpoint * ep = (struct fd_endpoint *)li;
     236                        if ( (fd_g_config->cnf_flags.no_ip4 && (ep->ss.ss_family == AF_INET))
     237                           ||(fd_g_config->cnf_flags.no_ip6 && (ep->ss.ss_family == AF_INET6)) ) {
     238                                li = li->prev;
     239                                fd_list_unlink(&ep->chain);
     240                                if (TRACE_BOOL(INFO)) {
     241                                        fd_log_debug("Info: Removing local address conflicting with the flags no_IP / no_IP6 : ");
     242                                        sSA_DUMP_NODE( &ep->ss, AI_NUMERICHOST );
     243                                        fd_log_debug("\n");
     244                                }
     245                                free(ep);
     246                        }
     247                }
     248        }
     249       
    231250        /* Configure TLS default parameters */
    232251        if (! fd_g_config->cnf_sec_data.prio_string) {
     
    239258        }
    240259        if (! fd_g_config->cnf_sec_data.dh_bits) {
    241                 TRACE_DEBUG(FULL, "Generating DH parameters...");
     260                if (TRACE_BOOL(INFO)) {
     261                        fd_log_debug("Generating Diffie-Hellman parameters of size %d (this takes a few seconds)... ", GNUTLS_DEFAULT_DHBITS);
     262                }
    242263                CHECK_GNUTLS_DO( gnutls_dh_params_generate2(
    243264                                        fd_g_config->cnf_sec_data.dh_cache,
    244265                                        GNUTLS_DEFAULT_DHBITS),
    245266                                 { TRACE_DEBUG(INFO, "Error in DH bits value : %d", GNUTLS_DEFAULT_DHBITS); return EINVAL; } );
    246                 TRACE_DEBUG(FULL, "DH parameters generated.");
    247         }
    248        
     267                if (TRACE_BOOL(INFO)) {
     268                        fd_log_debug("Done!\n");
     269                }
     270        }
    249271       
    250272        return 0;
  • freeDiameter/fD.h

    r21 r22  
    157157        ,FDEVP_TERMINATE
    158158       
     159        /* A connection object has received a message -- stored in event->data */
     160        ,FDEVP_CNX_MSG_RECV
     161       
    159162        /* A message was received in the peer */
    160163        ,FDEVP_MSG_INCOMING
     
    162165        /* The PSM state is expired */
    163166        ,FDEVP_PSM_TIMEOUT
     167       
    164168};
    165169const char * fd_pev_str(int event);
     
    196200void fd_servers_dump();
    197201int fd_servers_start();
    198 void fd_servers_stop();
     202int fd_servers_stop();
    199203
    200204/* Connection contexts */
    201 struct cnxctx * fd_cnx_init(int sock, int proto);
     205struct cnxctx * fd_cnx_serv_tcp(uint16_t port, int family, struct fd_endpoint * ep);
     206struct cnxctx * fd_cnx_serv_sctp(uint16_t port, struct fd_list * ep_list);
     207int fd_cnx_serv_listen(struct cnxctx * conn);
     208struct cnxctx * fd_cnx_serv_accept(struct cnxctx * serv);
     209struct cnxctx * fd_cnx_cli_connect(int proto, const sSA * sa,  socklen_t addrlen);
     210char * fd_cnx_getid(struct cnxctx * conn);
    202211int fd_cnx_start_clear(struct cnxctx * conn);
    203 int fd_cnx_handshake(struct cnxctx * conn, int mode);
     212int fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority);
    204213int fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsigned int *cert_list_size);
    205 int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * senti);
     214int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_list * remote);
    206215char * fd_cnx_getremoteid(struct cnxctx * conn);
    207216int fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len);
     217int fd_cnx_recv_setaltfifo(struct cnxctx * conn, struct fifo * alt_fifo); /* send FDEVP_CNX_MSG_RECV event to the fifo list */
    208218int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len);
    209219void fd_cnx_destroy(struct cnxctx * conn);
    210220
     221/* TCP */
     222int fd_tcp_create_bind_server( int * sock, sSA * sa, socklen_t salen );
     223int fd_tcp_listen( int sock );
     224
    211225/* SCTP */
    212226#ifndef DISABLE_SCTP
    213 int fd_sctp_create_bind_server( int * socket, uint16_t port );
     227int fd_sctp_create_bind_server( int * sock, struct fd_list * list, uint16_t port );
     228int fd_sctp_listen( int sock );
     229
    214230int fd_sctp_get_str_info( int socket, int *in, int *out );
    215231
  • freeDiameter/fdd.y

    r20 r22  
    336336                                /* Now destroy any content in the structure */
    337337                                free(fddpi.pi_diamid);
     338                                free(fddpi.pi_sec_data.priority);
    338339                                while (!FD_IS_LIST_EMPTY(&fddpi.pi_endpoints)) {
    339340                                        struct fd_list * li = fddpi.pi_endpoints.next;
     
    415416                                fddpi.pi_port = (uint16_t)$4;
    416417                        }
    417                         | peerparams SCTPSTREAMS '=' INTEGER ';'
    418                         {
    419                                 CHECK_PARAMS_DO( ($4 > 0) && ($4 < 1<<16),
    420                                         { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
    421                                 fddpi.pi_streams = (uint16_t)$4;
    422                         }
    423418                        | peerparams TCTIMER '=' INTEGER ';'
    424419                        {
    425420                                fddpi.pi_tctimer = $4;
     421                        }
     422                        | peerparams TLS_PRIO '=' QSTRING ';'
     423                        {
     424                                fddpi.pi_sec_data.priority = $4;
    426425                        }
    427426                        | peerparams TWTIMER '=' INTEGER ';'
  • freeDiameter/main.c

    r20 r22  
    5151struct fd_config * fd_g_config = &conf;
    5252
     53/* gcrypt functions to support posix threads */
    5354GCRY_THREAD_OPTION_PTHREAD_IMPL;
    5455
     
    105106        CHECK_FCT(  fd_ext_load()  );
    106107       
     108        /* Start the servers */
     109        CHECK_FCT( fd_servers_start() );
     110       
    107111        /* Start the peer state machines */
    108112        CHECK_FCT( fd_psm_start() );
     
    154158       
    155159        /* cleanups */
     160        CHECK_FCT_DO( fd_servers_stop(), /* Stop accepting new connections */ );
    156161        TODO("Stop dispatch thread(s) properly (no cancel yet)");
    157162        CHECK_FCT_DO( fd_peer_fini(), /* Stop all connections */ );
  • freeDiameter/p_expiry.c

    r16 r22  
    4747static void * gc_th_fct(void * arg)
    4848{
    49         fd_log_threadname ( "Peers/garbage" );
    50         TRACE_ENTRY( "" );
     49        fd_log_threadname ( "Peers/garb. col." );
     50        TRACE_ENTRY( "%p", arg );
    5151       
    5252        do {
    5353                struct fd_list * li, purge = FD_LIST_INITIALIZER(purge);
    5454               
    55                 pthread_testcancel();
    56                 sleep(GC_TIME);
     55                sleep(GC_TIME); /* sleep is a cancellation point */
    5756               
    5857                /* Now check in the peers list if any peer can be deleted */
     
    9695{
    9796        fd_log_threadname ( "Peers/expire" );
    98         TRACE_ENTRY( "" );
     97        TRACE_ENTRY( "%p", arg );
    9998       
    10099        CHECK_POSIX_DO( pthread_mutex_lock(&exp_mtx),  goto error );
     
    124123                       
    125124                        CHECK_POSIX_DO2(  pthread_cond_timedwait( &exp_cnd, &exp_mtx, &first->p_exp_timer ), 
    126                                         ETIMEDOUT, /* ETIMEDOUT is a normal error, continue */,
     125                                        ETIMEDOUT, /* ETIMEDOUT is a normal return value, continue */,
    127126                                        /* on other error, */ goto error );
    128127       
  • freeDiameter/p_psm.c

    r20 r22  
    5555        #define case_str( _val )\
    5656                case _val : return #_val
     57                case_str(FDEVP_DUMP_ALL);
    5758                case_str(FDEVP_TERMINATE);
    58                 case_str(FDEVP_DUMP_ALL);
     59                case_str(FDEVP_CNX_MSG_RECV);
    5960                case_str(FDEVP_MSG_INCOMING);
    6061                case_str(FDEVP_PSM_TIMEOUT);
     
    241242psm_end:
    242243        pthread_cleanup_pop(1); /* set STATE_ZOMBIE */
     244        pthread_detach(peer->p_psm);
     245        peer->p_psm = (pthread_t)NULL;
    243246        return NULL;
    244247}       
     
    267270        TRACE_ENTRY("%p", peer);
    268271        CHECK_PARAMS( CHECK_PEER(peer) );
     272       
    269273        if (peer->p_hdr.info.pi_state != STATE_ZOMBIE) {
    270274                CHECK_FCT( fd_event_send(peer->p_events, FDEVP_TERMINATE, NULL) );
  • freeDiameter/peers.c

    r20 r22  
    101101       
    102102        p->p_hdr.info.pi_lft     = info->pi_lft;
    103         p->p_hdr.info.pi_streams = info->pi_streams;
    104103        p->p_hdr.info.pi_port    = info->pi_port;
    105104        p->p_hdr.info.pi_tctimer = info->pi_tctimer;
    106105        p->p_hdr.info.pi_twtimer = info->pi_twtimer;
     106       
     107        if (info->pi_sec_data.priority) {
     108                CHECK_MALLOC( p->p_hdr.info.pi_sec_data.priority = strdup(info->pi_sec_data.priority) );
     109        }
    107110       
    108111        /* Move the items from one list to the other */
     
    113116                        fd_list_insert_before(&p->p_hdr.info.pi_endpoints, li);
    114117                }
     118       
    115119       
    116120        /* The internal data */
     
    229233       
    230234        if (p->p_cnxctx) {
    231                 TODO("destroy p->p_cnxctx");
     235                fd_cnx_destroy(p->p_cnxctx);
    232236        }
    233237       
     
    293297                list_empty = FD_IS_LIST_EMPTY(&fd_g_peers);
    294298                CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ );
     299                CHECK_SYS(  clock_gettime(CLOCK_REALTIME, &now)  );
    295300        }
    296301       
  • freeDiameter/sctp.c

    r20 r22  
    3636#include "fD.h"
    3737
    38 int fd_sctp_create_bind_server( int * socket, uint16_t port )
     38/* Create a socket server and bind it according to daemon s configuration */
     39int fd_sctp_create_bind_server( int * sock, struct fd_list * list, uint16_t port )
    3940{
    4041        TODO("Create sctp server, using fd_g_config: cnf_endpoints, no_ip4, no_ip6, cnf_sctp_str");
     
    4344}
    4445
     46/* Allow clients connections on server sockets */
     47int fd_sctp_listen( int sock )
     48{
     49        TRACE_ENTRY("%d", sock);
     50        CHECK_SYS( listen(sock, 5) );
     51        return 0;
     52}
     53
     54/* Retrieve streams information from a connected association */
    4555int fd_sctp_get_str_info( int socket, int *in, int *out )
    4656{
     
    4959        return ENOTSUP;
    5060}
     61
  • freeDiameter/server.c

    r21 r22  
    3636#include "fD.h"
    3737
    38 /* This file contains the server (listening) part of the daemon */
    39 
    40 struct fd_list          FD_SERVERS = FD_LIST_INITIALIZER(FD_SERVERS);   /* The list of all server sockets */
    41 /* We don't need to protect this list, it is only accessed from the main thread. */
    42 
    43 /* Server (listening socket) information */
     38/* Server (listening) part of the daemon */
     39
     40struct fd_list          FD_SERVERS = FD_LIST_INITIALIZER(FD_SERVERS);   /* The list of all server objects */
     41/* We don't need to protect this list, it is only accessed from the main daemon thread. */
     42
     43/* Servers information */
    4444struct server {
    4545        struct fd_list  chain;          /* link in the FD_SERVERS list */
    4646
    47         int             socket;         /* server socket, or <= 0 */
    48        
     47        struct cnxctx * conn;           /* server connection context (listening socket) */
    4948        int             proto;          /* IPPROTO_TCP or IPPROTO_SCTP */
    5049        int             secur;          /* TLS is started immediatly after connection ? */
    5150       
    52         pthread_t       serv_thr;       /* The thread listening for new connections */
    53         int             serv_status;    /* 0 : not created; 1 : running; 2 : terminated */
    54        
    55         pthread_mutex_t clients_mtx;    /* Mutex to protect the list of clients connected to the thread */
    56         struct fd_list  clients;        /* The list of clients connecting to this server, which information is not yet known */
    57        
    58         char *          serv_name;      /* A string to identify this server */
     51        pthread_t       thr;            /* The thread listening for new connections */
     52        int             status;         /* 0 : not created; 1 : running; 2 : terminated */
     53       
     54        struct fd_list  clients;        /* List of clients connected to this server, not yet identified */
     55        pthread_mutex_t clients_mtx;    /* Mutex to protect the list of clients */
    5956};
    6057
    61 /* Client (connected remote endpoint, not received CER yet) information */
     58/* Client information (connecting peer for which we don't have the CER yet) */
    6259struct client {
    6360        struct fd_list   chain; /* link in the server's list of clients */
    64         struct cnxctx   *conn;  /* Parameters of the connection; sends its events to the ev fifo bellow */
    65         struct timespec  ts;    /* Delay for receiving CER: INCNX_TIMEOUT */
    66         pthread_t        cli_thr; /* connection state machine (simplified PSM) */
     61        struct cnxctx   *conn;  /* Parameters of the connection */
     62        struct timespec  ts;    /* Deadline for receiving CER (after INCNX_TIMEOUT) */
     63        pthread_t        thr;   /* connection state machine */
    6764};
    6865
    69 /* Parameter for the thread handling the new connected client, to avoid bloking the server thread */
    70 struct cli_fast {
    71         struct server * serv;
    72         int             sock;
    73         sSS             ss;
    74         socklen_t       sslen;
    75 };
    76 
    77 
    78 static void * client_simple_psm(void * arg)
     66
     67/* Dump all servers information */
     68void fd_servers_dump()
     69{
     70        struct fd_list * li, *cli;
     71       
     72        fd_log_debug("Dumping servers list :\n");
     73        for (li = FD_SERVERS.next; li != &FD_SERVERS; li = li->next) {
     74                struct server * s = (struct server *)li;
     75                fd_log_debug("  Serv %p '%s': %s, %s, %s\n",
     76                                s, fd_cnx_getid(s->conn),
     77                                IPPROTO_NAME( s->proto ),
     78                                s->secur ? "Secur" : "NotSecur",
     79                                (s->status == 0) ? "Thread not created" :
     80                                ((s->status == 1) ? "Thread running" :
     81                                ((s->status == 2) ? "Thread terminated" :
     82                                                          "Thread status unknown")));
     83                /* Dump the client list of this server */
     84                (void) pthread_mutex_lock(&s->clients_mtx);
     85                for (cli = s->clients.next; cli != &s->clients; cli = cli->next) {
     86                        struct client * c = (struct client *)cli;
     87                        char bufts[128];
     88                        fd_log_debug("     Connected: '%s' (timeout: %s)\n",
     89                                        fd_cnx_getid(c->conn),
     90                                        fd_log_time(&c->ts, bufts, sizeof(bufts)));
     91                }
     92                (void) pthread_mutex_unlock(&s->clients_mtx);
     93        }
     94}
     95
     96
     97/* The state machine to handle incoming connection before the remote peer is identified */
     98static void * client_sm(void * arg)
    7999{
    80100        struct client * c = arg;
     
    88108       
    89109        /* 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 );
     110        fd_log_threadname ( fd_cnx_getid(c->conn) );
     111       
     112        /* Handshake if we are a secure server port, or start clear otherwise */
     113        if (s->secur) {
     114                int ret = fd_cnx_handshake(c->conn, GNUTLS_SERVER, NULL);
     115                if (ret != 0) {
     116                        if (TRACE_BOOL(INFO)) {
     117                                fd_log_debug("TLS handshake failed for client '%s', connection aborted.\n", fd_cnx_getid(c->conn));
     118                        }
     119                        goto cleanup;
     120                }
     121        } else {
     122                CHECK_FCT_DO( fd_cnx_start_clear(c->conn), goto cleanup );
    94123        }
    95124       
     
    104133        TODO("Message == CER : ");
    105134        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); ");
     135        TODO("Send event to the peer");
     136       
     137        /* The end */
     138cleanup:
     139        /* Unlink the client structure */
     140        CHECK_POSIX_DO( pthread_mutex_lock(&s->clients_mtx), goto fatal_error );
     141        fd_list_unlink( &c->chain );
     142        CHECK_POSIX_DO( pthread_mutex_unlock(&s->clients_mtx), goto fatal_error );
     143       
     144        /* Destroy the connection object if present */
     145        if (c->conn)
     146                fd_cnx_destroy(c->conn);
     147       
     148        /* Detach the thread, cleanup the client structure */
     149        pthread_detach(pthread_self());
     150        free(c);
    112151        return NULL;
    113152       
     
    117156}
    118157
    119 /* This thread is called when a new client had just connected */
    120 static void * handle_client_fast(void * arg)
    121 {
    122         struct cli_fast * cf = arg;
    123         struct client * c = NULL;
    124        
    125         /* Name the current thread */
    126         ASSERT(arg);
    127         {
    128                 char addr[128];
    129                 int offset = snprintf(addr, sizeof(addr), "Srv %d/CliFast %d : ", cf->serv->socket, cf->sock);
    130                 int rc = getnameinfo((sSA *)&cf->ss, sizeof(sSS), addr + offset, sizeof(addr) - offset, NULL, 0, 0);
    131                 if (rc)
    132                         memcpy(addr + offset, gai_strerror(rc), sizeof(addr) - offset);
    133                
    134                 fd_log_threadname ( addr );
    135        
    136                 if (TRACE_BOOL(INFO)) {
    137                         fd_log_debug( "New connection %s, sock %d, from '%s'\n", cf->serv->serv_name, cf->sock, addr + offset);
    138                 }
    139         }
    140        
    141         /* Create a client structure */
    142         CHECK_MALLOC_DO( c = malloc(sizeof(struct client)), goto fatal_error );
    143         memset(c, 0, sizeof(struct client));
    144         fd_list_init(&c->chain, c);
    145        
    146         /* Create the connection context */
    147         CHECK_MALLOC_DO( c->conn = fd_cnx_init(cf->sock, cf->serv->proto), goto fatal_error );
    148        
    149         /* In case we are a secure server, handshake now */
    150         if (cf->serv->secur) {
    151                 CHECK_FCT_DO( fd_cnx_handshake(c->conn, GNUTLS_CLIENT), goto cleanup );
    152         }
    153        
    154        
    155         /* Save the client in the list */
    156         CHECK_POSIX_DO( pthread_mutex_lock( &cf->serv->clients_mtx ), goto fatal_error );
    157         fd_list_insert_before(&cf->serv->clients, &c->chain);
    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        
    167 cleanup:        /* 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        
    174 fatal_error:    /* This has effect to terminate the daemon */
    175         CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, NULL), );
    176         free(cf);
    177         free(c);
    178         return NULL;
    179 }
    180 
    181 /* The thread for the server */
     158/* The thread managing a server */
    182159static void * serv_th(void * arg)
    183160{
    184         struct server *sv = (struct server *)arg;
    185         struct cli_fast cf;
    186         pthread_attr_t  attr;
    187        
    188         CHECK_PARAMS_DO(sv, goto error);
    189         fd_log_threadname ( sv->serv_name );
    190         sv->serv_status = 1;
    191        
    192         memset(&cf, 0, sizeof(struct cli_fast));
    193         cf.serv = sv;
    194        
    195         CHECK_POSIX_DO( pthread_attr_init(&attr), goto error );
    196         CHECK_POSIX_DO( pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED), goto error );
     161        struct server *s = (struct server *)arg;
     162       
     163        CHECK_PARAMS_DO(s, goto error);
     164        fd_log_threadname ( fd_cnx_getid(s->conn) );
     165        s->status = 1;
    197166       
    198167        /* Accept incoming connections */
    199         CHECK_SYS_DO(  listen(sv->socket, 5), goto error );
     168        CHECK_FCT_DO( fd_cnx_serv_listen(s->conn), goto error );
    200169       
    201170        do {
    202                 struct cli_fast * ncf;
    203                 pthread_t         thr;
    204                
    205                 /* Re-init socket size */
    206                 cf.sslen = sizeof(sSS);
     171                struct client * c = NULL;
     172                struct cnxctx * conn = NULL;
    207173               
    208174                /* Wait for a new client */
    209                 CHECK_SYS_DO( cf.sock = accept(sv->socket, (sSA *)&cf.ss, &cf.sslen), goto error );
     175                CHECK_MALLOC_DO( conn = fd_cnx_serv_accept(s->conn), goto error );
    210176               
    211177                TRACE_DEBUG(FULL, "New connection accepted");
    212178               
    213                 /* Create the copy for the client thread */
    214                 CHECK_MALLOC_DO( ncf = malloc(sizeof(struct cli_fast)), goto error );
    215                 memcpy(ncf, &cf, sizeof(struct cli_fast));
    216                
    217                 /* Create the thread to handle the new incoming connection */
    218                 CHECK_POSIX_DO( pthread_create( &thr, &attr, handle_client_fast, ncf), goto error );
     179                /* Create a client structure */
     180                CHECK_MALLOC_DO( c = malloc(sizeof(struct client)), goto error );
     181                memset(c, 0, sizeof(struct client));
     182                fd_list_init(&c->chain, c);
     183                c->conn = conn;
     184               
     185                /* Save the client in the list */
     186                CHECK_POSIX_DO( pthread_mutex_lock( &s->clients_mtx ), goto error );
     187                fd_list_insert_before(&s->clients, &c->chain);
     188                CHECK_POSIX_DO( pthread_mutex_unlock( &s->clients_mtx ), goto error );
     189
     190                /* Start the client thread */
     191                CHECK_POSIX_DO( pthread_create( &c->thr, NULL, client_sm, c ), goto error );
    219192               
    220193        } while (1);
    221194       
    222195error: 
    223         if (sv)
    224                 sv->serv_status = 2;
     196        if (s)
     197                s->status = 2;
    225198        /* Send error signal to the daemon */
    226199        TRACE_DEBUG(INFO, "An error occurred in server module! Thread is terminating...");
     
    232205
    233206/* Create a new server structure */
    234 static struct server * new_serv( int proto, int secur, int socket )
    235 {
    236         char buf[32];
    237         char * sn = NULL;
     207static struct server * new_serv( int proto, int secur )
     208{
    238209        struct server * new;
    239        
    240         /* Create the server debug name */
    241         buf[sizeof(buf) - 1] = '\0';
    242         snprintf(buf, sizeof(buf) - 1, "Serv %d (%s%s)", socket, IPPROTO_NAME( proto ), secur ? "s" : "");
    243         CHECK_MALLOC_DO( sn = strdup(buf), return NULL );
    244210       
    245211        /* New server structure */
     
    248214        memset(new, 0, sizeof(struct server));
    249215        fd_list_init(&new->chain, new);
    250         new->socket = socket;
    251216        new->proto = proto;
    252217        new->secur = secur;
     
    254219        fd_list_init(&new->clients, new);
    255220       
    256         new->serv_name = sn;
    257        
    258221        return new;
    259 }
    260 
    261 /* Dump all servers information */
    262 void fd_servers_dump()
    263 {
    264         struct fd_list * li;
    265        
    266         fd_log_debug("Dumping servers list :\n");
    267         for (li = FD_SERVERS.next; li != &FD_SERVERS; li = li->next) {
    268                 struct server * sv = (struct server *)li;
    269                 fd_log_debug("  Serv '%s': %s(%d), %s, %s, %s\n",
    270                                 sv->serv_name,
    271                                 (sv->socket > 0) ? "Open" : "Closed", sv->socket,
    272                                 IPPROTO_NAME( sv->proto ),
    273                                 sv->secur ? "Secur" : "NotSecur",
    274                                 (sv->serv_status == 0) ? "Thread not created" :
    275                                 ((sv->serv_status == 1) ? "Thread running" :
    276                                 ((sv->serv_status == 2) ? "Thread terminated" :
    277                                                           "Thread status unknown")));
    278                 /* Dump the client list */
    279                 TODO("Dump client list");
    280         }
    281222}
    282223
     
    284225int fd_servers_start()
    285226{
    286         int  socket;
    287         struct server * sv;
     227        struct server * s;
     228       
     229        int empty_conf_ep = FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints);
    288230       
    289231        /* SCTP */
     
    294236               
    295237                /* Create the server on default port */
    296                 CHECK_FCT( fd_sctp_create_bind_server( &socket, fd_g_config->cnf_port ) );
    297                 CHECK_MALLOC( sv = new_serv(IPPROTO_SCTP, 0, socket) );
    298                 TODO("Link");
    299                 TODO("Start thread");
     238                CHECK_MALLOC( s = new_serv(IPPROTO_SCTP, 0) );
     239                CHECK_MALLOC( s->conn = fd_cnx_serv_sctp(fd_g_config->cnf_port, FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints) ? NULL : &fd_g_config->cnf_endpoints) );
     240                fd_list_insert_before( &FD_SERVERS, &s->chain );
     241                CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) );
     242               
     243                /* Retrieve the list of endpoints if it was empty */
     244                if (empty_conf_ep) {
     245                        (void) fd_cnx_getendpoints(s->conn, &fd_g_config->cnf_endpoints, NULL);
     246                }
    300247               
    301248                /* Create the server on secure port */
     249                CHECK_MALLOC( s = new_serv(IPPROTO_SCTP, 1) );
     250                CHECK_MALLOC( s->conn = fd_cnx_serv_sctp(fd_g_config->cnf_port_tls, FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints) ? NULL : &fd_g_config->cnf_endpoints) );
     251                fd_list_insert_before( &FD_SERVERS, &s->chain );
     252                CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) );
    302253               
    303254#endif /* DISABLE_SCTP */
     
    307258        if (!fd_g_config->cnf_flags.no_tcp) {
    308259               
    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 :: */
     260                if (empty_conf_ep) {
     261                        /* Bind TCP servers on [0.0.0.0] */
     262                        if (!fd_g_config->cnf_flags.no_ip4) {
     263                               
     264                                CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 0) );
     265                                CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port, AF_INET, NULL) );
     266                                fd_list_insert_before( &FD_SERVERS, &s->chain );
     267                                CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) );
     268
     269                                CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 1) );
     270                                CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port_tls, AF_INET, NULL) );
     271                                fd_list_insert_before( &FD_SERVERS, &s->chain );
     272                                CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) );
     273                        }
     274                        /* Bind TCP servers on [::] */
     275                        if (!fd_g_config->cnf_flags.no_ip6) {
     276                               
     277                                CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 0) );
     278                                CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port, AF_INET6, NULL) );
     279                                fd_list_insert_before( &FD_SERVERS, &s->chain );
     280                                CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) );
     281
     282                                CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 1) );
     283                                CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port_tls, AF_INET6, NULL) );
     284                                fd_list_insert_before( &FD_SERVERS, &s->chain );
     285                                CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) );
     286                        }
    312287                } else {
    313288                        /* Create all endpoints -- check flags */
     289                        struct fd_list * li;
     290                        for (li = fd_g_config->cnf_endpoints.next; li != &fd_g_config->cnf_endpoints; li = li->next) {
     291                                struct fd_endpoint * ep = (struct fd_endpoint *)li;
     292                                sSA * sa = (sSA *) &ep->ss;
     293                                if (! ep->meta.conf)
     294                                        continue;
     295                                if (fd_g_config->cnf_flags.no_ip4 && (sa->sa_family == AF_INET))
     296                                        continue;
     297                                if (fd_g_config->cnf_flags.no_ip6 && (sa->sa_family == AF_INET6))
     298                                        continue;
     299                               
     300                                CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 0) );
     301                                CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port, sa->sa_family, ep) );
     302                                fd_list_insert_before( &FD_SERVERS, &s->chain );
     303                                CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) );
     304
     305                                CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 1) );
     306                                CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port_tls, sa->sa_family, ep) );
     307                                fd_list_insert_before( &FD_SERVERS, &s->chain );
     308                                CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) );
     309                        }
    314310                }
    315311        }
     
    319315
    320316/* Terminate all the servers */
    321 void fd_servers_stop()
    322 {
     317int fd_servers_stop()
     318{
     319        TODO("Not implemented");
     320       
    323321        /* Loop on all servers */
    324322                /* cancel thread */
    325                 /* shutdown the socket */
    326                 /* empty list of clients (stop them) */
    327 }
     323                /* destroy server connection context */
     324                /* cancel and destroy all clients */
     325}
  • include/freeDiameter/freeDiameter.h

    r20 r22  
    256256        /* Additional parameters */
    257257        uint32_t        pi_lft;         /* lifetime of this peer when inactive (see pi_flags.exp definition) */
    258         uint16_t        pi_streams;     /* number of streams for SCTP. 0 = default */
    259258        uint16_t        pi_port;        /* port to connect to. 0: default. */
    260259        int             pi_tctimer;     /* use this value for TcTimer instead of global, if != 0 */
     
    271270        struct fd_list  pi_apps;        /* applications advertised by the remote peer, except relay (pi_flags.relay) */
    272271        struct {
     272                char                    *priority;      /* In case the default priority is not appropriate */
    273273                /* This is inspired from http://www.gnu.org/software/gnutls/manual/gnutls.html#ex_003ax509_002dinfo */
    274274                const gnutls_datum_t    *cert_list;     /* The (valid) credentials that the peer has presented */
  • include/freeDiameter/libfreeDiameter.h

    r20 r22  
    120120 *
    121121 * PARAMETERS:
     122 *  ts          : The timestamp to log, or NULL for "now"
    122123 *  buf         : An array where the time must be stored
    123124 *  len         : size of the buffer
    124125 *
    125126 * DESCRIPTION:
    126  *  Writes the current timestamp (in human readable format) in a buffer.
     127 *  Writes the timestamp (in human readable format) in a buffer.
    127128 *
    128129 * RETURN VALUE:
    129130 *  pointer to buf.
    130131 */
    131 char * fd_log_time ( char * buf, size_t len );
     132char * fd_log_time ( struct timespec * ts, char * buf, size_t len );
    132133
    133134
     
    173174                fd_log_debug("\t | tid:%-20s\t%s\tin %s@%s:%d\n"                                                                \
    174175                          "\t%s|%*s" format "\n",                                                                               \
    175                                         __thn, fd_log_time(__buf, sizeof(__buf)), __PRETTY_FUNCTION__, __FILE__, __LINE__,      \
     176                                        __thn, fd_log_time(NULL, __buf, sizeof(__buf)), __PRETTY_FUNCTION__, __FILE__, __LINE__,        \
    176177                                        (level < FULL)?"@":" ",level, "", ## args);                                             \
    177178        }                                                                                                                       \
  • libfreeDiameter/log.c

    r2 r22  
    8787}
    8888
    89 /* Write current time into a buffer */
    90 char * fd_log_time ( char * buf, size_t len )
     89/* Write time into a buffer */
     90char * fd_log_time ( struct timespec * ts, char * buf, size_t len )
    9191{
    9292        int ret;
     
    9696       
    9797        /* Get current time */
    98         ret = clock_gettime(CLOCK_REALTIME, &tp);
    99         if (ret != 0) {
    100                 snprintf(buf, len, "%s", strerror(ret));
    101                 return buf;
     98        if (!ts) {
     99                ret = clock_gettime(CLOCK_REALTIME, &tp);
     100                if (ret != 0) {
     101                        snprintf(buf, len, "%s", strerror(ret));
     102                        return buf;
     103                }
     104                ts = &tp;
    102105        }
    103106       
    104         offset += strftime(buf + offset, len - offset, "%D,%T", localtime_r( &tp.tv_sec , &tm ));
    105         offset += snprintf(buf + offset, len - offset, ".%6.6ld", tp.tv_nsec / 1000);
     107        offset += strftime(buf + offset, len - offset, "%D,%T", localtime_r( &ts->tv_sec , &tm ));
     108        offset += snprintf(buf + offset, len - offset, ".%6.6ld", ts->tv_nsec / 1000);
    106109
    107110        return buf;
Note: See TracChangeset for help on using the changeset viewer.