Mercurial > hg > freeDiameter
changeset 28:3628f7d2ba88
some new functions backbones
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Mon, 26 Oct 2009 18:07:24 +0900 |
parents | b3a1773e9f46 |
children | 5ba91682f0bc |
files | freeDiameter/fD.h freeDiameter/p_psm.c freeDiameter/peers.c freeDiameter/server.c |
diffstat | 4 files changed, 99 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- a/freeDiameter/fD.h Mon Oct 26 16:48:47 2009 +0900 +++ b/freeDiameter/fD.h Mon Oct 26 18:07:24 2009 +0900 @@ -156,7 +156,7 @@ /* request to terminate this peer : disconnect, requeue all messages */ ,FDEVP_TERMINATE - /* A connection object has received a message. */ + /* A connection object has received a message. (data contains the buffer) */ ,FDEVP_CNX_MSG_RECV /* A connection object has encountered an error (disconnected). */ @@ -165,8 +165,8 @@ /* Endpoints of a connection have been changed (multihomed SCTP). */ ,FDEVP_CNX_EP_CHANGE - /* A message was received in the peer */ - ,FDEVP_MSG_INCOMING + /* A new connection has been established (data contains the appropriate info) */ + ,FDEVP_CNX_INCOMING /* The PSM state is expired */ ,FDEVP_PSM_TIMEOUT @@ -184,11 +184,12 @@ /* Functions */ -int fd_peer_fini(); +int fd_peer_fini(); void fd_peer_dump_list(int details); void fd_peer_dump(struct fd_peer * peer, int details); -int fd_peer_alloc(struct fd_peer ** ptr); -int fd_peer_free(struct fd_peer ** ptr); +int fd_peer_alloc(struct fd_peer ** ptr); +int fd_peer_free(struct fd_peer ** ptr); +int fd_peer_handle_newCER( struct msg ** cer, struct cnxctx ** cnx, int tls_done ); /* fd_peer_add declared in freeDiameter.h */ /* Peer expiry */ @@ -197,33 +198,33 @@ int fd_p_expi_update(struct fd_peer * peer ); /* Peer state machine */ -int fd_psm_start(); -int fd_psm_begin(struct fd_peer * peer ); -int fd_psm_terminate(struct fd_peer * peer ); +int fd_psm_start(); +int fd_psm_begin(struct fd_peer * peer ); +int fd_psm_terminate(struct fd_peer * peer ); void fd_psm_abord(struct fd_peer * peer ); /* Server sockets */ void fd_servers_dump(); -int fd_servers_start(); -int fd_servers_stop(); +int fd_servers_start(); +int fd_servers_stop(); -/* Connection contexts */ +/* Connection contexts -- there are also definitions in cnxctx.h for the relevant files */ struct cnxctx * fd_cnx_serv_tcp(uint16_t port, int family, struct fd_endpoint * ep); struct cnxctx * fd_cnx_serv_sctp(uint16_t port, struct fd_list * ep_list); -int fd_cnx_serv_listen(struct cnxctx * conn); +int fd_cnx_serv_listen(struct cnxctx * conn); struct cnxctx * fd_cnx_serv_accept(struct cnxctx * serv); 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 loop); -int fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority); -int fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsigned int *cert_list_size); -int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_list * remote); -char * fd_cnx_getremoteid(struct cnxctx * conn); -int fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len); -int fd_cnx_recv_setaltfifo(struct cnxctx * conn, struct fifo * alt_fifo); /* send FDEVP_CNX_MSG_RECV event to the fifo list */ -int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len); -void fd_cnx_destroy(struct cnxctx * conn); +char * fd_cnx_getid(struct cnxctx * conn); +int fd_cnx_start_clear(struct cnxctx * conn, int loop); +int fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority); +int fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsigned int *cert_list_size); +int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_list * remote); +char * fd_cnx_getremoteid(struct cnxctx * conn); +int fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len); +int fd_cnx_recv_setaltfifo(struct cnxctx * conn, struct fifo * alt_fifo); /* send FDEVP_CNX_MSG_RECV event to the fifo list */ +int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len); +void fd_cnx_destroy(struct cnxctx * conn); #endif /* _FD_H */
--- a/freeDiameter/p_psm.c Mon Oct 26 16:48:47 2009 +0900 +++ b/freeDiameter/p_psm.c Mon Oct 26 18:07:24 2009 +0900 @@ -59,7 +59,7 @@ case_str(FDEVP_CNX_MSG_RECV); case_str(FDEVP_CNX_ERROR); case_str(FDEVP_CNX_EP_CHANGE); - case_str(FDEVP_MSG_INCOMING); + case_str(FDEVP_CNX_INCOMING); case_str(FDEVP_PSM_TIMEOUT); default: @@ -226,9 +226,6 @@ peer->p_psm = (pthread_t)NULL; return NULL; } - - - /* Create the PSM thread of one peer structure */ int fd_psm_begin(struct fd_peer * peer )
--- a/freeDiameter/peers.c Mon Oct 26 16:48:47 2009 +0900 +++ b/freeDiameter/peers.c Mon Oct 26 18:07:24 2009 +0900 @@ -130,9 +130,9 @@ CHECK_POSIX( pthread_rwlock_wrlock(&fd_g_peers_rw) ); for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { - struct fd_peer * prev = (struct fd_peer *)li; - int cmp = strcasecmp( p->p_hdr.info.pi_diamid, prev->p_hdr.info.pi_diamid ); - if (cmp < 0) + struct fd_peer * next = (struct fd_peer *)li; + int cmp = strcasecmp( p->p_hdr.info.pi_diamid, next->p_hdr.info.pi_diamid ); + if (cmp > 0) continue; if (cmp == 0) ret = EEXIST; @@ -374,3 +374,69 @@ CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ ); } +/* Handle an incoming CER request on a new connection */ +int fd_peer_handle_newCER( struct msg ** cer, struct cnxctx ** cnx, int tls_done ) +{ + struct msg * msg; + struct dict_object *avp_oh_model; + avp_code_t code = AC_ORIGIN_HOST; + struct avp *avp_oh; + struct avp_hdr * avp_hdr; + struct fd_list * li; + int found = 0; + struct fd_peer * peer; + + TRACE_ENTRY("%p %p %d", cer, cnx, tls_done); + CHECK_PARAMS(cer && *cer && cnx && *cnx); + + msg = *cer; + + /* Find the Diameter Identity of the remote peer in the message */ + CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_CODE, &code, &avp_oh_model, ENOENT) ); + CHECK_FCT( fd_msg_search_avp ( msg, avp_oh_model, &avp_oh ) ); + CHECK_FCT( fd_msg_avp_hdr ( avp_oh, &avp_hdr ) ); + + /* Search if we already have this peer id in our list */ + CHECK_POSIX( pthread_rwlock_rdlock(&fd_g_peers_rw) ); + + for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { + peer = (struct fd_peer *)li; + int cmp = strncasecmp( avp_hdr->avp_value->os.data, peer->p_hdr.info.pi_diamid, avp_hdr->avp_value->os.len ); + if (cmp > 0) + continue; + if (cmp == 0) + found = 1; + break; + } + + if (!found) { + + TODO("Create a new peer entry with this diameter id (pf_responder = 1)"); + TODO("Upgrade the lock to wr"); + TODO("Add the new peer in the list"); + TODO("Release the wr lock"); + TODO("Start the peer PSM, which will have to validate if this peer is authorized to connect, and so on"); + } + + TODO("Send the new connection event to the peer SM with the appropriate data: msg, conn, tls_done, found"); + /* FDEVP_CNX_INCOMING */ + + /* Reset the "out" parameters, so that they are not cleanup on function return. */ + *cer = NULL; + *cnx = NULL; + + CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) ); + + + TODO("(later if not tls_done) handshake or start_clear(.., 1) "); + + return 0; +} + +/* Save a callback to accept / reject incoming unknown peers */ +int fd_peer_validate_register ( int (*peer_validate)(struct peer_info * /* info */, int * /* auth */, int (**cb2)(struct peer_info *)) ) +{ + + TODO("..."); + return ENOTSUP; +}
--- a/freeDiameter/server.c Mon Oct 26 16:48:47 2009 +0900 +++ b/freeDiameter/server.c Mon Oct 26 18:07:24 2009 +0900 @@ -138,8 +138,8 @@ /* Try parsing this message */ CHECK_FCT_DO( fd_msg_parse_buffer( &buf, bufsz, &msg ), /* Parsing failed */ goto cleanup ); - /* We expect a CER, it must parse with our dictionary */ - CHECK_FCT_DO( fd_msg_parse_dict( msg, fd_g_config->cnf_dict ), /* Parsing failed */ goto cleanup ); + /* We expect a CER, it must parse with our dictionary and rules */ + CHECK_FCT_DO( fd_msg_parse_rules( msg, fd_g_config->cnf_dict, NULL ), /* Parsing failed -- trace details ? */ goto cleanup ); if (TRACE_BOOL(FULL)) { fd_log_debug("Received Diameter message from new client '%s':\n", fd_cnx_getid(c->conn)); @@ -148,16 +148,13 @@ /* Now check we received a CER */ CHECK_FCT_DO( fd_msg_hdr ( msg, &hdr ), goto fatal_error ); - CHECK_PARAMS_DO( (hdr->msg_appl == 0) && (hdr->msg_flags & CMD_FLAG_REQUEST) && (hdr->msg_code == CC_CAPABILITIES_EXCHANGE), { fd_log_debug("Connection '%s', expecting CER, received something else, closing...\n", fd_cnx_getid(c->conn)); goto cleanup; } ); + /* Finally, pass the information to the peers module which will handle it next */ + CHECK_FCT_DO( fd_peer_handle_newCER( &msg, &c->conn, s->secur ), goto fatal_error ); - TODO("Search matching peer"); - TODO("Send event to the peer"); - - TODO("(later) handshake or start_clear(.., 1)"); - /* The end */ + /* The end, we cleanup the client structure */ cleanup: /* Unlink the client structure */ CHECK_POSIX_DO( pthread_mutex_lock(&s->clients_mtx), goto fatal_error );