# HG changeset patch # User Sebastien Decugis # Date 1245045610 -32400 # Node ID c7ce13cb7d230b81a05e380ac0d57d99f6983c65 # Parent 844f921713d5d3e3de9e543dbab558a8a3416a1e Removed session cache in the radius_clients since we are stateless diff -r 844f921713d5 -r c7ce13cb7d23 extensions/radius_gw/rgw_clients.c --- a/extensions/radius_gw/rgw_clients.c Mon Jun 15 13:37:13 2009 +0900 +++ b/extensions/radius_gw/rgw_clients.c Mon Jun 15 15:00:10 2009 +0900 @@ -35,9 +35,11 @@ /* Manage the list of RADIUS clients, along with their shared secrets. */ +/* Probably some changes are needed to support RADIUS Proxy */ + #include "radius_gw.h" -/* How many bytes of secret keys to dump? */ +/* How many bytes of shared secrets to dump? */ #define KEY_DUMP_BYTES 16 /* Ordered lists of clients. The order relationship is a memcmp on the address zone. @@ -57,14 +59,14 @@ /* Reference count */ int refcount; - /* The address and optional port. */ + /* The address and optional port (alloc'd during configuration file parsing). */ union { struct sockaddr *sa; /* generic pointer */ struct sockaddr_in *sin; struct sockaddr_in6 *sin6; }; - /* The FQDN and optional aliases */ + /* The FQDN, realm, and optional aliases */ char *fqdn; char *realm; char **aliases; @@ -76,29 +78,14 @@ size_t len; } key; - /* information of previous msg received, for duplicate checks. [0] for auth, [1] for acct. */ + /* information of previous msg received, for duplicate checks. */ struct { uint16_t port; uint8_t id; - struct radius_msg * ans; /* to be able to resend the lost answer */ - } last[2]; - - /* User sessions attached to this client (ordered by session-id) */ - struct rg_list sessions; /* list of struct rgw_client_session */ + struct radius_msg * ans; /* to be able to resend a lost answer */ + } last[2]; /*[0] for auth, [1] for acct. */ }; -struct rgw_client_session { - struct rg_list chain; - char * sid; - sess_id_t *session; - char * dest_host; - char * dest_realm; - application_id_t appid; -}; - -static dict_object_t * str_dict = NULL; - - /* create a new rgw_client. the arguments are moved into the structure. */ static int client_create(struct rgw_client ** res, struct sockaddr ** ip_port, unsigned char ** key, size_t keylen ) { @@ -117,7 +104,6 @@ CHECK_MALLOC( tmp = malloc(sizeof (struct rgw_client)) ); memset(tmp, 0, sizeof(struct rgw_client)); rg_list_init(&tmp->chain); - rg_list_init(&tmp->sessions); /* Copy the fqdn */ CHECK_MALLOC( tmp->fqdn = strdup(buf) ); @@ -153,10 +139,6 @@ /* to be sure: the refcount should be 0 only when client_fini is called */ ASSERT( rg_list_is_empty(&client->chain) ); - /* All sessions should have been deleted also */ - ASSERT( rg_list_is_empty(&client->sessions) ); - - /* Free the data */ for (idx = 0; idx < client->aliases_nb; idx++) free(client->aliases[idx]); @@ -255,7 +237,6 @@ } } - int rgw_clients_getkey(struct rgw_client * cli, unsigned char **key, size_t *key_len) { CHECK_PARAMS( cli && key && key_len ); @@ -523,7 +504,6 @@ { rg_list_init(&cli_ip); rg_list_init(&cli_ip6); - CHECK_FCT( dict_search ( DICT_COMMAND, CMD_BY_NAME, "Session-Termination-Request", &str_dict, ENOENT) ); return 0; } @@ -712,229 +692,3 @@ return 0; } -/* New user session attached to the client. Server info is needed */ -int rgw_client_session_add(struct rgw_client * cli, sess_id_t *sess, char * dest_realm, char * dest_host, application_id_t appid) -{ - struct rgw_client_session * new; - struct rg_list * li; - - TRACE_ENTRY("%p %p %p %p %d", cli, sess, dest_realm, dest_host, appid); - CHECK_PARAMS(cli && sess && dest_realm); - - CHECK_MALLOC(new = malloc(sizeof(struct rgw_client_session))); - memset(new, 0, sizeof(*new)); - rg_list_init(&new->chain); - - /* Increment the session refcount */ - CHECK_FCT( sess_link(sess) ); - - /* Get the session name */ - CHECK_FCT( sess_getsid(sess, &new->sid) ); - new->session = sess; - - /* Copy other information */ - CHECK_MALLOC( new->dest_realm = strdup(dest_realm) ); - if (dest_host) { - CHECK_MALLOC( new->dest_host = strdup(dest_host) ); - } - new->appid = appid; - - /* Now insert in the client's list */ - for (li = cli->sessions.next; li != &cli->sessions; li = li->next) { - struct rgw_client_session *sli = (struct rgw_client_session *)li; - int cmp = strcmp(new->sid, sli->sid); - if (cmp <= 0) - break; - } - rg_list_insert_before(li, &new->chain); - - return 0; -} - -static void sta_cb(void * data, msg_t ** answer) -{ - TRACE_ENTRY("%p %p"); - - /* We should destroy all data associated to this session here */ - TRACE_DEBUG(INFO, "Received STA, should destroy the session data, not implemented yet..."); - -} - -static int send_str(sess_id_t * sess, int32_t reason, char * orig_host, char * orig_realm, char * dest_host, char * dest_realm, application_id_t appid) -{ - char * sid; - char * reason_str = "unknown"; - msg_t * str; - dict_type_enum_request_t get_reason_name = - { - .type_name = "Enumerated(Termination-Cause)", - .search.enum_name=NULL, - .search.enum_value.i32 = reason - }; - dict_object_t * reason_enum; - - TRACE_ENTRY("%p %u %s %s %s %s %d", sess, reason, orig_host, orig_realm, dest_host, dest_realm, appid); - CHECK_PARAMS(sess && orig_host && orig_realm && dest_realm); - - CHECK_FCT( sess_getsid(sess, &sid) ); - - CHECK_FCT( dict_search ( DICT_TYPE_ENUM, ENUM_BY_STRUCT, &get_reason_name, &reason_enum, 0) ); - if (reason_enum) { - dict_type_enum_data_t reason_data; - CHECK_FCT( dict_getval ( reason_enum, &reason_data ) ); - reason_str = reason_data.enum_name; - } - TRACE_DEBUG(INFO, "Terminating session '%s', cause %s (%d).", sid, reason_str, reason); - - /* Now ,create the STR message */ - CHECK_FCT( msg_new(str_dict, MSGFL_ALLOW_ETEID, &str) ); - - /* Add the Session-Id */ - { - dict_object_t * avp_dict; - avp_value_t value; - msg_avp_t * avp; - CHECK_FCT( dict_search( DICT_AVP, AVP_BY_NAME, "Session-Id", &avp_dict, ENOENT)); - CHECK_FCT( msg_avp_new ( avp_dict, 0, &avp ) ); - value.os.data = sid; - value.os.len = strlen(sid); - CHECK_FCT( msg_avp_setvalue ( avp, &value ) ); - CHECK_FCT( msg_avp_add ( str, MSG_BRW_FIRST_CHILD, avp) ); - } - /* Add the Origin-Host */ - { - dict_object_t * avp_dict; - avp_value_t value; - msg_avp_t * avp; - CHECK_FCT( dict_search( DICT_AVP, AVP_BY_NAME, "Origin-Host", &avp_dict, ENOENT)); - CHECK_FCT( msg_avp_new ( avp_dict, 0, &avp ) ); - value.os.data = orig_host; - value.os.len = strlen(orig_host); - CHECK_FCT( msg_avp_setvalue ( avp, &value ) ); - CHECK_FCT( msg_avp_add ( str, MSG_BRW_LAST_CHILD, avp) ); - } - /* Add the Origin-Realm */ - { - dict_object_t * avp_dict; - avp_value_t value; - msg_avp_t * avp; - CHECK_FCT( dict_search( DICT_AVP, AVP_BY_NAME, "Origin-Realm", &avp_dict, ENOENT)); - CHECK_FCT( msg_avp_new ( avp_dict, 0, &avp ) ); - value.os.data = orig_realm; - value.os.len = strlen(orig_realm); - CHECK_FCT( msg_avp_setvalue ( avp, &value ) ); - CHECK_FCT( msg_avp_add ( str, MSG_BRW_LAST_CHILD, avp) ); - } - /* Add the Destination-Realm */ - { - dict_object_t * avp_dict; - avp_value_t value; - msg_avp_t * avp; - CHECK_FCT( dict_search( DICT_AVP, AVP_BY_NAME, "Destination-Realm", &avp_dict, ENOENT)); - CHECK_FCT( msg_avp_new ( avp_dict, 0, &avp ) ); - value.os.data = dest_realm; - value.os.len = strlen(dest_realm); - CHECK_FCT( msg_avp_setvalue ( avp, &value ) ); - CHECK_FCT( msg_avp_add ( str, MSG_BRW_LAST_CHILD, avp) ); - } - /* Add the Destination-Host */ - if (dest_host) { - dict_object_t * avp_dict; - avp_value_t value; - msg_avp_t * avp; - CHECK_FCT( dict_search( DICT_AVP, AVP_BY_NAME, "Destination-Host", &avp_dict, ENOENT)); - CHECK_FCT( msg_avp_new ( avp_dict, 0, &avp ) ); - value.os.data = dest_host; - value.os.len = strlen(dest_host); - CHECK_FCT( msg_avp_setvalue ( avp, &value ) ); - CHECK_FCT( msg_avp_add ( str, MSG_BRW_LAST_CHILD, avp) ); - } - /* Add the Auth-Application-Id */ - { - dict_object_t * avp_dict; - avp_value_t value; - msg_avp_t * avp; - CHECK_FCT( dict_search( DICT_AVP, AVP_BY_NAME, "Auth-Application-Id", &avp_dict, ENOENT)); - CHECK_FCT( msg_avp_new ( avp_dict, 0, &avp ) ); - value.i32 = appid; - CHECK_FCT( msg_avp_setvalue ( avp, &value ) ); - CHECK_FCT( msg_avp_add ( str, MSG_BRW_LAST_CHILD, avp) ); - } - /* also in the header of the message */ - { - msg_data_t *str_data; - CHECK_FCT( msg_data ( str, &str_data ) ); - str_data->msg_appl = appid; - } - /* Add the Termination-Cause */ - { - dict_object_t * avp_dict; - avp_value_t value; - msg_avp_t * avp; - CHECK_FCT( dict_search( DICT_AVP, AVP_BY_NAME, "Termination-Cause", &avp_dict, ENOENT)); - CHECK_FCT( msg_avp_new ( avp_dict, 0, &avp ) ); - value.i32 = reason; - CHECK_FCT( msg_avp_setvalue ( avp, &value ) ); - CHECK_FCT( msg_avp_add ( str, MSG_BRW_LAST_CHILD, avp) ); - } - /* Add a Route-Record for our host */ - { - dict_object_t * avp_dict; - avp_value_t value; - msg_avp_t * avp; - CHECK_FCT( dict_search( DICT_AVP, AVP_BY_NAME, "Route-Record", &avp_dict, ENOENT)); - CHECK_FCT( msg_avp_new ( avp_dict, 0, &avp ) ); - value.os.data = g_pconf->diameter_identity; - value.os.len = strlen(g_pconf->diameter_identity); - CHECK_FCT( msg_avp_setvalue ( avp, &value ) ); - CHECK_FCT( msg_avp_add ( str, MSG_BRW_LAST_CHILD, avp) ); - } - - /* Send this message */ - CHECK_FCT( msg_send( &str, sta_cb, NULL ) ); - - return 0; -} - -static int sli_str_free(struct rgw_client_session *sli, struct rgw_client * cli, int32_t reason) -{ - CHECK_FCT( send_str(sli->session, reason, cli->fqdn, cli->realm, sli->dest_host, sli->dest_realm, sli->appid) ); - rg_list_unlink(&sli->chain); - CHECK_FCT( sess_unlink ( &sli->session ) ); - free(sli->dest_host); - free(sli->dest_realm); - free(sli); - return 0; -} - -/* if sess is NULL, all sessions are stopped on this client */ -int rgw_client_session_stop(struct rgw_client * cli, sess_id_t * sess, int32_t reason) -{ - struct rg_list * li; - struct rgw_client_session *sli; - - TRACE_ENTRY("%p %p", cli, sess); - CHECK_PARAMS(cli); - - if (sess != NULL) { - /* Search this session in the list */ - for (li = cli->sessions.next; li != &cli->sessions; li = li->next) { - sli = (struct rgw_client_session *)li; - if (sli->session == sess) - break; - sli = NULL; - } - /* Found it */ - if (sli != NULL) { - CHECK_FCT( sli_str_free(sli, cli, reason) ); - } else { - TRACE_DEBUG(FULL, "Session %p not found in this RADIUS client's list, ignore", sess); - } - } else { - for (li = cli->sessions.next; li != &cli->sessions; li = li->next) { - sli = (struct rgw_client_session *)li; - CHECK_FCT( sli_str_free(sli, cli, reason) ); - } - } - return 0; -}