Commit d27604b2 authored by Sebastien Decugis's avatar Sebastien Decugis
Browse files

Added some code in cnxctx.c mainly

parent ae5d6418
......@@ -67,6 +67,7 @@
# Default : listen on all addresses available.
#ListenOn = "202.249.37.5";
#ListenOn = "2001:200:903:2::202:1";
#ListenOn = "fe80::21c:5ff:fe98:7d62%eth0";
##############################################################
## TLS Configuration
......@@ -200,13 +201,11 @@ Realm = "wide.ad.jp";
Port = 3866;
SecPort = 3867;
TLS_old_method;
No_SCTP;
Prefer_TCP;
SCTP_streams = 50;
#ListenOn = "202.249.37.5";
#ListenOn = "2001:200:903:2::202:1";
TcTimer = 60;
TwTimer = 6;
ListenOn = "133.243.146.201";
ListenOn = "fe80::21d:9ff:fe89:7d68%eth0";
NoRelay;
LoadExtension = "extensions/dbg_monitor.fdx";
LoadExtension = "extensions/dict_nasreq.fdx";
......
......@@ -213,9 +213,11 @@ int fd_cnx_serv_listen(struct cnxctx * conn)
CHECK_FCT(fd_tcp_listen(conn->cc_socket));
break;
#ifndef DISABLE_SCTP
case IPPROTO_SCTP:
CHECK_FCT(fd_sctp_listen(conn->cc_socket));
break;
#endif /* DISABLE_SCTP */
default:
CHECK_PARAMS(0);
......@@ -399,7 +401,7 @@ int fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsig
return ENOTSUP;
}
/* Get the list of endpoints (IP addresses) of the local and remote peers on this conenction */
/* Get the list of endpoints (IP addresses) of the local and remote peers on this connection */
int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_list * remote)
{
TRACE_ENTRY("%p %p %p", conn, local, remote);
......@@ -407,18 +409,54 @@ int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_
if (local) {
/* Retrieve the local endpoint(s) of the connection */
TODO("TCP : getsockname");
TODO("SCTP: sctp_getladdrs / _sctp_getboundaddrs (waaad)");
switch (conn->cc_proto) {
case IPPROTO_TCP: {
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 ));
}
break;
#ifndef DISABLE_SCTP
case IPPROTO_SCTP: {
CHECK_FCT(fd_sctp_get_local_ep(conn->cc_socket, local));
}
break;
#endif /* DISABLE_SCTP */
default:
CHECK_PARAMS(0);
}
}
if (remote) {
/* Retrieve the peer endpoint(s) of the connection */
TODO("TCP : getpeername");
TODO("SCTP: sctp_getpaddrs");
/* Check we have a full connection object, not a listening socket (with no remote) */
CHECK_PARAMS( conn->cc_events );
/* Retrieve the peer endpoint(s) of the connection */
switch (conn->cc_proto) {
case IPPROTO_TCP: {
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 ));
}
break;
#ifndef DISABLE_SCTP
case IPPROTO_SCTP: {
CHECK_FCT(fd_sctp_get_remote_ep(conn->cc_socket, remote));
}
break;
#endif /* DISABLE_SCTP */
default:
CHECK_PARAMS(0);
}
}
return ENOTSUP;
return 0;
}
......
......@@ -99,7 +99,7 @@ void fd_conf_dump()
while (li != &fd_g_config->cnf_endpoints) {
struct fd_endpoint * ep = (struct fd_endpoint *)li;
if (li != fd_g_config->cnf_endpoints.next) fd_log_debug(" ");
sSA_DUMP_NODE( &ep->ss, NI_NUMERICHOST );
sSA_DUMP_NODE( &ep->sa, NI_NUMERICHOST );
fd_log_debug("\n");
li = li->next;
}
......@@ -233,13 +233,13 @@ int fd_conf_parse()
struct fd_list * li;
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;
if ( (fd_g_config->cnf_flags.no_ip4 && (ep->ss.ss_family == AF_INET))
||(fd_g_config->cnf_flags.no_ip6 && (ep->ss.ss_family == AF_INET6)) ) {
if ( (fd_g_config->cnf_flags.no_ip4 && (ep->sa.sa_family == AF_INET))
||(fd_g_config->cnf_flags.no_ip6 && (ep->sa.sa_family == AF_INET6)) ) {
li = li->prev;
fd_list_unlink(&ep->chain);
if (TRACE_BOOL(INFO)) {
fd_log_debug("Info: Removing local address conflicting with the flags no_IP / no_IP6 : ");
sSA_DUMP_NODE( &ep->ss, AI_NUMERICHOST );
sSA_DUMP_NODE( &ep->sa, AI_NUMERICHOST );
fd_log_debug("\n");
}
free(ep);
......@@ -271,3 +271,43 @@ 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;
}
......@@ -221,12 +221,15 @@ 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_get_local_ep(int sock, sSS * ss, socklen_t *sl);
int fd_tcp_get_remote_ep(int sock, sSS * ss, socklen_t *sl);
/* SCTP */
#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_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 );
#endif /* DISABLE_SCTP */
......
......@@ -211,25 +211,16 @@ sctpstreams: SCTPSTREAMS '=' INTEGER ';'
listenon: LISTENON '=' QSTRING ';'
{
struct fd_endpoint * ep;
struct addrinfo hints, *ai;
int ret;
CHECK_MALLOC_DO( ep = malloc(sizeof(struct fd_endpoint)),
{ yyerror (&yylloc, conf, "Out of memory"); YYERROR; } );
memset(ep, 0, sizeof(struct fd_endpoint));
fd_list_init(&ep->chain, NULL);
ep->meta.conf = 1;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
ret = getaddrinfo($3, NULL, &hints, &ai);
if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); free(ep); YYERROR; }
ASSERT( ai->ai_addrlen <= sizeof(sSS) );
memcpy(&ep->ss, ai->ai_addr, ai->ai_addrlen);
free($3);
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 );
freeaddrinfo(ai);
fd_list_insert_before(&conf->cnf_endpoints, &ep->chain);
free($3);
}
;
......@@ -429,30 +420,24 @@ peerparams: /* empty */
}
| peerparams CONNTO '=' QSTRING ';'
{
struct fd_endpoint * ep;
struct addrinfo hints, *ai;
int ret;
int disc = 0;
CHECK_MALLOC_DO( ep = malloc(sizeof(struct fd_endpoint)),
{ yyerror (&yylloc, conf, "Out of memory"); YYERROR; } );
memset(ep, 0, sizeof(struct fd_endpoint));
fd_list_init(&ep->chain, NULL);
ep->meta.conf = 1;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST;
ret = getaddrinfo($4, NULL, &hints, &ai);
if (ret == EAI_NONAME) {
/* The name was maybe not numeric, try again */
ep->meta.disc = 1;
disc = 1;
hints.ai_flags &= ~ AI_NUMERICHOST;
ret = getaddrinfo($4, NULL, &hints, &ai);
}
if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); free(ep); YYERROR; }
if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); YYERROR; }
memcpy(&ep->ss, ai->ai_addr, ai->ai_addrlen);
CHECK_FCT_DO( fd_ep_add_merge( &fddpi.pi_endpoints, ai->ai_addr, ai->ai_addrlen, 1, disc, 0, 0 ), YYERROR );
free($4);
freeaddrinfo(ai);
fd_list_insert_before(&fddpi.pi_endpoints, &ep->chain);
}
;
......
......@@ -105,6 +105,8 @@ int main(int argc, char * argv[])
/* Load the dynamic extensions */
CHECK_FCT( fd_ext_load() );
fd_conf_dump();
/* Start the servers */
CHECK_FCT( fd_servers_start() );
......@@ -113,7 +115,6 @@ int main(int argc, char * argv[])
/* Now, just wait for events */
TRACE_DEBUG(INFO, FD_PROJECT_BINARY " daemon initialized.");
fd_conf_dump();
while (1) {
int code;
CHECK_FCT_DO( fd_event_get(fd_g_config->cnf_main_ev, &code, NULL), break );
......
This diff is collapsed.
......@@ -36,6 +36,7 @@
#include "fD.h"
#include <netinet/tcp.h>
#include <netinet/ip6.h>
#include <sys/socket.h>
/* Set the socket options for TCP sockets, before bind is called */
static int fd_tcp_setsockopt(int family, int sk)
......@@ -110,3 +111,27 @@ int fd_tcp_listen( int sock )
CHECK_SYS( listen(sock, 5) );
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)
{
TRACE_ENTRY("%d %p %p", sock, ss, sl);
CHECK_PARAMS( ss && sl );
*sl = sizeof(sSS);
CHECK_SYS(getsockname(sock, (sSA *)ss, sl));
return 0;
}
/* Get the remote name of a TCP socket */
int fd_tcp_get_remote_ep(int sock, sSS * ss, socklen_t *sl)
{
TRACE_ENTRY("%d %p %p", sock, ss, sl);
CHECK_PARAMS( ss && sl );
*sl = sizeof(sSS);
CHECK_SYS(getpeername(sock, (sSA *)ss, sl));
return 0;
}
......@@ -9,7 +9,10 @@ Project("freeDiameter include directory" C)
OPTION(DEFAULT_CONF_FILE "Default path to configuration file?" OFF)
# Disable SCTP support completly ?
OPTION(DISABLE_SCTP "Disable SCTP support?")
OPTION(DISABLE_SCTP "Disable SCTP support?" OFF)
IF (NOT DISABLE_SCTP)
OPTION(DEBUG_SCTP "Verbose SCTP (for debug)?" OFF)
ENDIF (NOT DISABLE_SCTP)
# Find TODO items in the code easily ?
OPTION(ERRORS_ON_TODO "(development) Generate compilation errors on TODO items ?" OFF)
......
......@@ -44,6 +44,7 @@
#cmakedefine HOST_BIG_ENDIAN @HOST_BIG_ENDIAN@
#cmakedefine DISABLE_SCTP
#cmakedefine DEBUG_SCTP
#cmakedefine ERRORS_ON_TODO
#cmakedefine DEBUG
......
......@@ -117,7 +117,12 @@ 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 */
sSS ss; /* the socket information. List is always ordered by ss value (memcmp) */
union {
sSS ss; /* the socket information. List is always ordered by ss value (memcmp) */
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 */
......@@ -129,6 +134,9 @@ struct fd_endpoint {
} meta; /* Additional information about the endpoint */
};
/* 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. */
......
......@@ -328,14 +328,55 @@ extern int fd_g_debug_lvl;
0, \
flag); \
if (__rc) \
fd_log_debug((char *)gai_strerror(__rc)); \
fd_log_debug("%s", (char *)gai_strerror(__rc)); \
else \
fd_log_debug(&__addrbuf[0]); \
fd_log_debug("%s", &__addrbuf[0]); \
} else { \
fd_log_debug("(NULL / ANY)"); \
} \
}
/* if needed, add sSA_DUMP_SERVICE */
/* 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 */
#define sSA_DUMP_NODE_SERV( sa, flag ) { \
sSA * __sa = (sSA *)(sa); \
char __addrbuf[INET6_ADDRSTRLEN]; \
char __servbuf[32]; \
if (__sa) { \
int __rc = getnameinfo(__sa, \
sizeof(sSS), \
__addrbuf, \
sizeof(__addrbuf), \
__servbuf, \
sizeof(__servbuf), \
flag); \
if (__rc) \
fd_log_debug("%s", (char *)gai_strerror(__rc)); \
else \
fd_log_debug("[%s]:%s", &__addrbuf[0],&__servbuf[0]); \
} else { \
fd_log_debug("(NULL / ANY)"); \
} \
}
/* A l4 protocol name (TCP / SCTP) */
#define IPPROTO_NAME( _proto ) \
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment