Commit 146fe937 authored by Sebastien Decugis's avatar Sebastien Decugis
Browse files

Cleanups and completed sctp code (not finished)

parent d27604b2
......@@ -204,8 +204,8 @@ TLS_old_method;
SCTP_streams = 50;
TcTimer = 60;
TwTimer = 6;
ListenOn = "133.243.146.201";
ListenOn = "fe80::21d:9ff:fe89:7d68%eth0";
#ListenOn = "133.243.146.201";
#ListenOn = "fe80::21d:9ff:fe89:7d68%eth0";
NoRelay;
LoadExtension = "extensions/dbg_monitor.fdx";
LoadExtension = "extensions/dict_nasreq.fdx";
......
......@@ -12,6 +12,7 @@ SET(FD_COMMON_SRC
config.c
cnxctx.c
dispatch.c
endpoints.c
extensions.c
dict_base_proto.c
messages.c
......
......@@ -173,9 +173,15 @@ error:
fd_cnx_destroy(cnx);
return NULL;
}
#ifndef DISABLE_SCTP
/* Same function for SCTP, with a list of local endpoints to bind to */
struct cnxctx * fd_cnx_serv_sctp(uint16_t port, struct fd_list * ep_list)
{
#ifdef DISABLE_SCTP
TRACE_DEBUG(INFO, "This function should never been called when SCTP is disabled...");
ASSERT(0);
CHECK_FCT_DO( ENOTSUP, return NULL);
#else /* DISABLE_SCTP */
struct cnxctx * cnx = NULL;
sSS dummy;
sSA * sa = (sSA *) &dummy;
......@@ -200,8 +206,8 @@ struct cnxctx * fd_cnx_serv_sctp(uint16_t port, struct fd_list * ep_list)
error:
fd_cnx_destroy(cnx);
return NULL;
}
#endif /* DISABLE_SCTP */
}
/* Allow clients to connect on the server socket */
int fd_cnx_serv_listen(struct cnxctx * conn)
......@@ -238,12 +244,13 @@ struct cnxctx * fd_cnx_serv_accept(struct cnxctx * serv)
TRACE_ENTRY("%p", serv);
CHECK_PARAMS_DO(serv, return NULL);
/* Accept the new connection -- this is blocking until new client enters or cancellation */
CHECK_SYS_DO( cli_sock = accept(serv->cc_socket, (sSA *)&ss, &ss_len), return NULL );
if (TRACE_BOOL(INFO)) {
fd_log_debug("%s - new client [", fd_cnx_getid(serv));
sSA_DUMP_NODE( &ss, AI_NUMERICHOST );
fd_log_debug("] connected.\n");
fd_log_debug("%s : accepted new client [", fd_cnx_getid(serv));
sSA_DUMP_NODE( &ss, NI_NUMERICHOST );
fd_log_debug("].\n");
}
CHECK_MALLOC_DO( cli = fd_cnx_init(1), { shutdown(cli_sock, SHUT_RDWR); return NULL; } );
......@@ -258,25 +265,27 @@ struct cnxctx * fd_cnx_serv_accept(struct cnxctx * serv)
/* Numeric values for debug */
rc = getnameinfo((sSA *)&ss, sizeof(sSS), addrbuf, sizeof(addrbuf), portbuf, sizeof(portbuf), NI_NUMERICHOST | NI_NUMERICSERV);
if (rc)
if (rc) {
snprintf(addrbuf, sizeof(addrbuf), "[err:%s]", gai_strerror(rc));
portbuf[0] = '\0';
}
snprintf(cli->cc_id, sizeof(cli->cc_id), "Client %s [%s]:%s (%d) / serv (%d)",
snprintf(cli->cc_id, sizeof(cli->cc_id), "Incoming %s [%s]:%s (%d) @ serv (%d)",
IPPROTO_NAME(cli->cc_proto),
addrbuf, portbuf,
cli->cc_socket, serv->cc_socket);
/* Textual value for log messages */
rc = getnameinfo((sSA *)&ss, sizeof(sSS), cli->cc_remid, sizeof(cli->cc_remid), NULL, 0, NI_NUMERICHOST);
/* Name for log messages */
rc = getnameinfo((sSA *)&ss, sizeof(sSS), cli->cc_remid, sizeof(cli->cc_remid), NULL, 0, 0);
if (rc)
snprintf(cli->cc_remid, sizeof(cli->cc_remid), "[err:%s]", gai_strerror(rc));
}
/* SCTP-specific handlings */
#ifndef DISABLE_SCTP
/* SCTP-specific handlings */
if (cli->cc_proto == IPPROTO_SCTP) {
/* Retrieve the number of streams */
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 );
CHECK_FCT_DO( fd_sctp_get_str_info( cli->cc_socket, &cli->cc_sctp_para.str_in, &cli->cc_sctp_para.str_out, NULL ), goto error );
if (cli->cc_sctp_para.str_out > cli->cc_sctp_para.str_in)
cli->cc_sctp_para.pairs = cli->cc_sctp_para.str_out;
else
......@@ -290,12 +299,121 @@ error:
return NULL;
}
/* Client side: connect to a remote server */
struct cnxctx * fd_cnx_cli_connect(int proto, const sSA * sa, socklen_t addrlen)
/* Client side: connect to a remote server -- cancelable */
struct cnxctx * fd_cnx_cli_connect_tcp(sSA * sa /* contains the port already */, socklen_t addrlen)
{
int sock;
struct cnxctx * cnx = NULL;
TRACE_ENTRY("%p %d", sa, addrlen);
CHECK_PARAMS_DO( sa && addrlen, return NULL );
/* Create the socket and connect, which can take some time and/or fail */
CHECK_FCT_DO( fd_tcp_client( &sock, sa, addrlen ), return NULL );
if (TRACE_BOOL(INFO)) {
fd_log_debug("Connection established to server '");
sSA_DUMP_NODE_SERV( sa, NI_NUMERICSERV);
fd_log_debug("' (TCP:%d).\n", sock);
}
/* Once the socket is created successfuly, prepare the remaining of the cnx */
CHECK_MALLOC_DO( cnx = fd_cnx_init(1), { shutdown(sock, SHUT_RDWR); return NULL; } );
cnx->cc_socket = sock;
cnx->cc_proto = IPPROTO_TCP;
/* Generate the names for the object */
{
char addrbuf[INET6_ADDRSTRLEN];
char portbuf[10];
int rc;
/* Numeric values for debug */
rc = getnameinfo(sa, addrlen, addrbuf, sizeof(addrbuf), portbuf, sizeof(portbuf), NI_NUMERICHOST | NI_NUMERICSERV);
if (rc) {
snprintf(addrbuf, sizeof(addrbuf), "[err:%s]", gai_strerror(rc));
portbuf[0] = '\0';
}
snprintf(cnx->cc_id, sizeof(cnx->cc_id), "Client of TCP server [%s]:%s (%d)", addrbuf, portbuf, cnx->cc_socket);
/* Name for log messages */
rc = getnameinfo(sa, addrlen, cnx->cc_remid, sizeof(cnx->cc_remid), NULL, 0, 0);
if (rc)
snprintf(cnx->cc_remid, sizeof(cnx->cc_remid), "[err:%s]", gai_strerror(rc));
}
return cnx;
TODO("...");
error:
fd_cnx_destroy(cnx);
return NULL;
}
/* Same for SCTP, accepts a list of remote addresses to connect to (see sctp_connectx) */
struct cnxctx * fd_cnx_cli_connect_sctp(int no_ip6, uint16_t port, struct fd_list * list)
{
#ifdef DISABLE_SCTP
TRACE_DEBUG(INFO, "This function should never been called when SCTP is disabled...");
ASSERT(0);
CHECK_FCT_DO( ENOTSUP, return NULL);
#else /* DISABLE_SCTP */
int sock;
struct cnxctx * cnx = NULL;
sSS primary;
TRACE_ENTRY("%p", list);
CHECK_PARAMS_DO( list && !FD_IS_LIST_EMPTY(list), return NULL );
CHECK_FCT_DO( fd_sctp_client( &sock, no_ip6, port, list ), return NULL );
/* Once the socket is created successfuly, prepare the remaining of the cnx */
CHECK_MALLOC_DO( cnx = fd_cnx_init(1), { shutdown(sock, SHUT_RDWR); return NULL; } );
cnx->cc_socket = sock;
cnx->cc_proto = IPPROTO_SCTP;
/* Retrieve the number of streams and primary address */
CHECK_FCT_DO( fd_sctp_get_str_info( sock, &cnx->cc_sctp_para.str_in, &cnx->cc_sctp_para.str_out, &primary ), goto error );
if (cnx->cc_sctp_para.str_out > cnx->cc_sctp_para.str_in)
cnx->cc_sctp_para.pairs = cnx->cc_sctp_para.str_out;
else
cnx->cc_sctp_para.pairs = cnx->cc_sctp_para.str_in;
/* Generate the names for the object */
{
char addrbuf[INET6_ADDRSTRLEN];
char portbuf[10];
int rc;
/* Numeric values for debug */
rc = getnameinfo((sSA *)&primary, sizeof(sSS), addrbuf, sizeof(addrbuf), portbuf, sizeof(portbuf), NI_NUMERICHOST | NI_NUMERICSERV);
if (rc) {
snprintf(addrbuf, sizeof(addrbuf), "[err:%s]", gai_strerror(rc));
portbuf[0] = '\0';
}
snprintf(cnx->cc_id, sizeof(cnx->cc_id), "Client of SCTP server [%s]:%s (%d)", addrbuf, portbuf, cnx->cc_socket);
/* Name for log messages */
rc = getnameinfo((sSA *)&primary, sizeof(sSS), cnx->cc_remid, sizeof(cnx->cc_remid), NULL, 0, 0);
if (rc)
snprintf(cnx->cc_remid, sizeof(cnx->cc_remid), "[err:%s]", gai_strerror(rc));
}
if (TRACE_BOOL(INFO)) {
fd_log_debug("Connection established to server '");
sSA_DUMP_NODE_SERV( &primary, NI_NUMERICSERV);
fd_log_debug("' (SCTP:%d).\n", sock);
}
return cnx;
error:
fd_cnx_destroy(cnx);
return NULL;
#endif /* DISABLE_SCTP */
}
/* Return a string describing the connection, for debug */
......@@ -414,7 +532,7 @@ int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_
sSS ss;
socklen_t sl;
CHECK_FCT(fd_tcp_get_local_ep(conn->cc_socket, &ss, &sl));
CHECK_FCT(fd_ep_add_merge( local, (sSA *)&ss, sl, 0, 0, 0, 1 ));
CHECK_FCT(fd_ep_add_merge( local, (sSA *)&ss, sl, EP_FL_LL | EP_FL_PRIMARY));
}
break;
......@@ -440,7 +558,7 @@ int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_
sSS ss;
socklen_t sl;
CHECK_FCT(fd_tcp_get_remote_ep(conn->cc_socket, &ss, &sl));
CHECK_FCT(fd_ep_add_merge( remote, (sSA *)&ss, sl, 0, 0, 0, 1 ));
CHECK_FCT(fd_ep_add_merge( remote, (sSA *)&ss, sl, EP_FL_LL | EP_FL_PRIMARY ));
}
break;
......@@ -527,7 +645,3 @@ void fd_cnx_destroy(struct cnxctx * conn)
/* Done! */
return;
}
......@@ -271,43 +271,3 @@ int fd_conf_parse()
return 0;
}
/* Add an endpoint information in a list */
int fd_ep_add_merge( struct fd_list * list, sSA * sa, socklen_t sl, int conf, int disc, int adv, int ll )
{
struct fd_endpoint * ep;
struct fd_list * li;
int cmp = -1;
TRACE_ENTRY("%p %p %u %i %i %i %i", list, sa, sl, conf, disc, adv, ll);
CHECK_PARAMS( list && sa && (sl <= sizeof(sSS)) && (conf || disc || adv || ll) );
/* Search place in the list */
for (li = list->next; li != list; li = li->next) {
ep = (struct fd_endpoint *)li;
cmp = memcmp(&ep->ss, sa, sl);
if (cmp >= 0)
break;
}
if (cmp) {
/* new item to be added */
CHECK_MALLOC( ep = malloc(sizeof(struct fd_endpoint)) );
memset(ep, 0, sizeof(struct fd_endpoint));
fd_list_init(&ep->chain, NULL);
memcpy(&ep->ss, sa, sl);
/* Insert in the list */
fd_list_insert_before(li, &ep->chain);
}
/* Merge the flags */
ep->meta.conf = conf || ep->meta.conf;
ep->meta.disc = disc || ep->meta.disc;
ep->meta.adv = adv || ep->meta.adv;
ep->meta.ll = ll || ep->meta.ll;
return 0;
}
/*********************************************************************************************************
* Software License Agreement (BSD License) *
* Author: Sebastien Decugis <sdecugis@nict.go.jp> *
* *
* Copyright (c) 2009, WIDE Project and NICT *
* All rights reserved. *
* *
* Redistribution and use of this software in source and binary forms, with or without modification, are *
* permitted provided that the following conditions are met: *
* *
* * Redistributions of source code must retain the above *
* copyright notice, this list of conditions and the *
* following disclaimer. *
* *
* * Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the *
* following disclaimer in the documentation and/or other *
* materials provided with the distribution. *
* *
* * Neither the name of the WIDE Project or NICT nor the *
* names of its contributors may be used to endorse or *
* promote products derived from this software without *
* specific prior written permission of WIDE Project and *
* NICT. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
*********************************************************************************************************/
#include "fD.h"
/* Add an endpoint information in a list */
int fd_ep_add_merge( struct fd_list * list, sSA * sa, socklen_t sl, uint32_t flags )
{
struct fd_endpoint * ep;
struct fd_list * li;
int cmp = -1;
TRACE_ENTRY("%p %p %u %x", list, sa, sl, flags);
CHECK_PARAMS( list && sa && (sl <= sizeof(sSS)) );
/* Search place in the list */
for (li = list->next; li != list; li = li->next) {
ep = (struct fd_endpoint *)li;
cmp = memcmp(&ep->ss, sa, sl);
if (cmp >= 0)
break;
}
if (cmp) {
/* new item to be added */
CHECK_MALLOC( ep = malloc(sizeof(struct fd_endpoint)) );
memset(ep, 0, sizeof(struct fd_endpoint));
fd_list_init(&ep->chain, NULL);
memcpy(&ep->ss, sa, sl);
/* Insert in the list */
fd_list_insert_before(li, &ep->chain);
}
/* Merge the flags */
ep->flags |= flags;
return 0;
}
/* Delete endpoints that do not have a matching flag from a list (0: delete all endpoints) */
int fd_ep_filter( struct fd_list * list, uint32_t flags )
{
struct fd_list * li;
TRACE_ENTRY("%p %x", list, flags);
CHECK_PARAMS(list);
for (li = list->next; li != list; li = li->next) {
struct fd_endpoint * ep = (struct fd_endpoint *)li;
if (! (ep->flags & flags)) {
li = li->prev;
fd_list_unlink(&ep->chain);
free(ep);
}
}
return 0;
}
/* Reset the given flag(s) from all items in the list */
int fd_ep_clearflags( struct fd_list * list, uint32_t flags )
{
struct fd_list * li;
TRACE_ENTRY("%p %x", list, flags);
CHECK_PARAMS(list);
for (li = list->next; li != list; li = li->next) {
struct fd_endpoint * ep = (struct fd_endpoint *)li;
ep->flags &= ~flags;
}
return 0;
}
......@@ -206,7 +206,8 @@ struct cnxctx * fd_cnx_serv_tcp(uint16_t port, int family, struct fd_endpoint *
struct cnxctx * fd_cnx_serv_sctp(uint16_t port, struct fd_list * ep_list);
int fd_cnx_serv_listen(struct cnxctx * conn);
struct cnxctx * fd_cnx_serv_accept(struct cnxctx * serv);
struct cnxctx * fd_cnx_cli_connect(int proto, const sSA * sa, socklen_t addrlen);
struct cnxctx * fd_cnx_cli_connect_tcp(sSA * sa, socklen_t addrlen);
struct cnxctx * fd_cnx_cli_connect_sctp(int no_ip6, uint16_t port, struct fd_list * list);
char * fd_cnx_getid(struct cnxctx * conn);
int fd_cnx_start_clear(struct cnxctx * conn);
int fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority);
......@@ -221,6 +222,7 @@ void fd_cnx_destroy(struct cnxctx * conn);
/* TCP */
int fd_tcp_create_bind_server( int * sock, sSA * sa, socklen_t salen );
int fd_tcp_listen( int sock );
int fd_tcp_client( int *sock, sSA * sa, socklen_t salen );
int fd_tcp_get_local_ep(int sock, sSS * ss, socklen_t *sl);
int fd_tcp_get_remote_ep(int sock, sSS * ss, socklen_t *sl);
......@@ -228,9 +230,10 @@ int fd_tcp_get_remote_ep(int sock, sSS * ss, socklen_t *sl);
#ifndef DISABLE_SCTP
int fd_sctp_create_bind_server( int * sock, struct fd_list * list, uint16_t port );
int fd_sctp_listen( int sock );
int fd_sctp_client( int *sock, int no_ip6, uint16_t port, struct fd_list * list );
int fd_sctp_get_local_ep(int sock, struct fd_list * list);
int fd_sctp_get_remote_ep(int sock, struct fd_list * list);
int fd_sctp_get_str_info( int socket, int *in, int *out );
int fd_sctp_get_str_info( int sock, int *in, int *out, sSS *primary );
#endif /* DISABLE_SCTP */
......
......@@ -218,7 +218,7 @@ listenon: LISTENON '=' QSTRING ';'
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
ret = getaddrinfo($3, NULL, &hints, &ai);
if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); YYERROR; }
CHECK_FCT_DO( fd_ep_add_merge( &conf->cnf_endpoints, ai->ai_addr, ai->ai_addrlen, 1, 0, 0, 0 ), YYERROR );
CHECK_FCT_DO( fd_ep_add_merge( &conf->cnf_endpoints, ai->ai_addr, ai->ai_addrlen, EP_FL_CONF ), YYERROR );
freeaddrinfo(ai);
free($3);
}
......@@ -429,13 +429,13 @@ peerparams: /* empty */
ret = getaddrinfo($4, NULL, &hints, &ai);
if (ret == EAI_NONAME) {
/* The name was maybe not numeric, try again */
disc = 1;
disc = EP_FL_DISC;
hints.ai_flags &= ~ AI_NUMERICHOST;
ret = getaddrinfo($4, NULL, &hints, &ai);
}
if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); YYERROR; }
CHECK_FCT_DO( fd_ep_add_merge( &fddpi.pi_endpoints, ai->ai_addr, ai->ai_addrlen, 1, disc, 0, 0 ), YYERROR );
CHECK_FCT_DO( fd_ep_add_merge( &fddpi.pi_endpoints, ai->ai_addr, ai->ai_addrlen, EP_FL_CONF | disc ), YYERROR );
free($4);
freeaddrinfo(ai);
}
......
This diff is collapsed.
......@@ -290,7 +290,7 @@ int fd_servers_start()
for (li = fd_g_config->cnf_endpoints.next; li != &fd_g_config->cnf_endpoints; li = li->next) {
struct fd_endpoint * ep = (struct fd_endpoint *)li;
sSA * sa = (sSA *) &ep->ss;
if (! ep->meta.conf)
if (! (ep->flags & EP_FL_CONF))
continue;
if (fd_g_config->cnf_flags.no_ip4 && (sa->sa_family == AF_INET))
continue;
......
......@@ -112,6 +112,32 @@ int fd_tcp_listen( int sock )
return 0;
}
/* Create a client socket and connect to remote server */
int fd_tcp_client( int *sock, sSA * sa, socklen_t salen )
{
TRACE_ENTRY("%p %p %d", sock, sa, salen);
CHECK_PARAMS( sock && sa && salen );
/* Create the socket */
CHECK_SYS( *sock = socket(sa->sa_family, SOCK_STREAM, IPPROTO_TCP) );
/* Cleanup if we are cancelled */
pthread_cleanup_push(fd_cleanup_socket, sock);
/* Set the socket options */
CHECK_FCT( fd_tcp_setsockopt(sa->sa_family, *sock) );
TRACE_DEBUG_sSA(FULL, "Attempting TCP connection with peer: ", sa, NI_NUMERICHOST | NI_NUMERICSERV, "..." );
/* Try connecting to the remote address */
CHECK_SYS( connect(*sock, sa, salen) );
/* Done! */
pthread_cleanup_pop(0);
return 0;
}
/* Get the local name of a TCP socket -- would be nice if it did not return "0.0.0.0"... */
int fd_tcp_get_local_ep(int sock, sSS * ss, socklen_t *sl)
{
......
......@@ -12,6 +12,7 @@ OPTION(DEFAULT_CONF_FILE "Default path to configuration file?" OFF)
OPTION(DISABLE_SCTP "Disable SCTP support?" OFF)
IF (NOT DISABLE_SCTP)
OPTION(DEBUG_SCTP "Verbose SCTP (for debug)?" OFF)
OPTION(SCTP_USE_MAPPED_ADDRESSES "Use v6-mapped v4 addresses in SCTP (workaround some SCTP limitations)?" OFF)
ENDIF (NOT DISABLE_SCTP)
# Find TODO items in the code easily ?
......
......@@ -45,6 +45,7 @@
#cmakedefine DISABLE_SCTP
#cmakedefine DEBUG_SCTP
#cmakedefine SCTP_USE_MAPPED_ADDRESSES
#cmakedefine ERRORS_ON_TODO
#cmakedefine DEBUG
......
......@@ -117,26 +117,24 @@ extern struct fd_config *fd_g_config; /* The pointer to access the global config
/* Endpoints */
struct fd_endpoint {
struct fd_list chain; /* link in cnf_endpoints list */
union {
sSS ss; /* the socket information. List is always ordered by ss value (memcmp) */
sSS ss; /* the socket information. List is always ordered by ss value (memcmp) -- see fd_ep_add_merge */
sSA4 sin;
sSA6 sin6;
sSA sa;
};
struct {
unsigned conf : 1; /* This endpoint is statically configured in a configuration file */
unsigned disc : 1; /* This endpoint was resolved from the Diameter Identity or other DNS query */
unsigned adv : 1; /* This endpoint was advertized in Diameter CER/CEA exchange */
unsigned ll : 1; /* Lower layer mechanism provided this endpoint */
#define EP_FL_CONF (1 << 0) /* This endpoint is statically configured in a configuration file */
#define EP_FL_DISC (1 << 1) /* This endpoint was resolved from the Diameter Identity or other DNS query */
#define EP_FL_ADV (1 << 2) /* This endpoint was advertized in Diameter CER/CEA exchange */
#define EP_FL_LL (1 << 3) /* Lower layer mechanism provided this endpoint */
#define EP_FL_PRIMARY (1 << 4) /* This endpoint is primary in a multihomed SCTP association */
uint32_t flags; /* Additional information about the endpoint */
/* To add: a validity timestamp for DNS records ? How do we retrieve this lifetime from DNS ? */
} meta; /* Additional information about the endpoint */
/* To add: a validity timestamp for DNS records ? How do we retrieve this lifetime from DNS ? */
};
/* Add a new entry in a list of endpoints -- merge if the sockaddr was already there */
int fd_ep_add_merge( struct fd_list * list, sSA * sa, socklen_t sl, int conf, int disc, int adv, int ll );
/* Applications */
struct fd_app {
struct fd_list chain; /* link in cnf_apps list. List ordered by appid. */
......@@ -467,4 +465,14 @@ int fd_disp_app_support ( struct dict_object * app, struct dict_object * vendor,
/* Note: if we want to support capabilities updates, we'll have to add possibility to remove an app as well... */
/***************************************/
/* Endpoints lists helpers */
/***************************************/
int fd_ep_add_merge( struct fd_list * list, sSA * sa, socklen_t sl, uint32_t flags );
int fd_ep_filter( struct fd_list * list, uint32_t flags );
int fd_ep_clearflags( struct fd_list * list, uint32_t flags );
#endif /* _FREEDIAMETER_H */
......@@ -335,27 +335,7 @@ extern int fd_g_debug_lvl;
fd_log_debug("(NULL / ANY)"); \
} \
}
/* Same, for a service */
#define sSA_DUMP_SERV( sa, flag ) { \
sSA * __sa = (sSA *)(sa); \
char __servbuf[32]; \
if (__sa) { \
int __rc = getnameinfo(__sa, \
sizeof(sSS), \
NULL, \
0, \
__servbuf, \
sizeof(__servbuf), \
flag); \
if (__rc) \
fd_log_debug("%s", (char *)gai_strerror(__rc)); \
else \
fd_log_debug("%s", &__servbuf[0]); \
} else { \
fd_log_debug("(unknown)"); \
} \
}
/* Combine both */
/* Same but with the port (service) also */
#define sSA_DUMP_NODE_SERV( sa, flag ) { \
sSA * __sa = (sSA *)(sa); \
char __addrbuf[INET6_ADDRSTRLEN]; \
......@@ -376,6 +356,19 @@ extern int fd_g_debug_lvl;
fd_log_debug("(NULL / ANY)"); \
} \
}
/* Inside a debug trace */
#define TRACE_DEBUG_sSA(level, prefix, sa, flags, suffix ) { \
if ( TRACE_BOOL(level) ) { \
char __buf[25]; \
char * __thn = ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed"); \
fd_log_debug("\t | tid:%-20s\t%s\tin %s@%s:%d