diff --git a/lib/s6a/s6a_app.c b/lib/s6a/s6a_app.c index 0c860fd95d..7307c10bb7 100644 --- a/lib/s6a/s6a_app.c +++ b/lib/s6a/s6a_app.c @@ -9,15 +9,12 @@ static pthread_t s6a_stats_th = (pthread_t)NULL; static void s6a_config_dump(void) { d_trace(1, "------- s6a configuration dump: ---------\n"); - d_trace(1, " Vendor Id .......... : %u\n", s6a_config->vendor_id); - d_trace(1, " Application Id ..... : %u\n", s6a_config->appli_id); d_trace(1, " Mode ............... : %s%s\n", s6a_config->mode & MODE_MME ? "MME" : "", s6a_config->mode & MODE_HSS ? "HSS" : ""); - d_trace(1, " Destination Realm .. : %s\n", - s6a_config->dest_realm ?: "- none -\n"); - d_trace(1, " Destination Host ... : %s\n", - s6a_config->dest_host ?: "- none -\n"); + d_trace(1, " Vendor Id .......... : %u\n", s6a_config->vendor_id); + d_trace(1, " Application Id ..... : %u\n", s6a_config->appli_id); + d_trace(1, " Duration ........... : %d(sec)\n", s6a_config->duration); d_trace(1, "------- /s6a configuration dump ---------\n"); } @@ -25,7 +22,7 @@ static void s6a_config_dump(void) static void * s6a_stats(void * arg) { struct timespec start, now; - struct ta_stats copy; + struct s6a_stats copy; /* Get the start time */ CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &start), ); @@ -33,11 +30,11 @@ static void * s6a_stats(void * arg) /* Now, loop until canceled */ while (1) { /* Display statistics every XX seconds */ - sleep(10); + sleep(s6a_config->duration); /* Now, get the current stats */ CHECK_POSIX_DO( pthread_mutex_lock(&s6a_config->stats_lock), ); - memcpy(©, &s6a_config->stats, sizeof(struct ta_stats)); + memcpy(©, &s6a_config->stats, sizeof(struct s6a_stats)); CHECK_POSIX_DO( pthread_mutex_unlock(&s6a_config->stats_lock), ); /* Get the current execution time */ diff --git a/lib/s6a/s6a_app.h b/lib/s6a/s6a_app.h index a19ec87010..ce55878aa6 100644 --- a/lib/s6a/s6a_app.h +++ b/lib/s6a/s6a_app.h @@ -31,13 +31,12 @@ struct s6a_config_t { char *pi_diamid; c_uint16_t pic_port; /* port to connect to. 0: default. */ - c_uint32_t vendor_id; /* default 999999 */ - c_uint32_t appli_id; /* default 123456 */ - int mode; /* default MODE_SERV | MODE_CLI */ - char *dest_realm; /* default local realm */ - char *dest_host; /* default NULL */ - char *user_name; /* default NULL */ - struct ta_stats { + int mode; /* default MODE_MME | MODE_HSS */ + c_uint32_t vendor_id; /* default 10415 */ + c_uint32_t appli_id; /* default 16777251 */ + + int duration; /* default 10 */ + struct s6a_stats { unsigned long long nb_echoed; /* server */ unsigned long long nb_sent; /* client */ unsigned long long nb_recv; /* client */ diff --git a/lib/s6a/s6a_config.c b/lib/s6a/s6a_config.c index 748f13f9a5..c13b5bdf92 100644 --- a/lib/s6a/s6a_config.c +++ b/lib/s6a/s6a_config.c @@ -97,16 +97,10 @@ static int s6a_common_config(void) s6a_config = &g_conf; /* Set the default values */ + s6a_config->mode = MODE_MME | MODE_HSS; s6a_config->vendor_id = 10415; /* 3GPP Vendor ID */ s6a_config->appli_id = 16777251; /* 3GPP S6A Application ID */ - s6a_config->mode = MODE_MME | MODE_HSS; -#if 0 - s6a_config->dest_realm = strdup(fd_g_config->cnf_diamrlm); -#else - s6a_config->dest_realm = strdup(MME_REALM); -#endif - s6a_config->dest_host = NULL; - s6a_config->user_name = strdup("01045238277"); + s6a_config->duration = 10; /* 10 seconds */ return 0; } diff --git a/lib/s6a/s6a_fd.c b/lib/s6a/s6a_fd.c index 25e7098f18..7647840226 100644 --- a/lib/s6a/s6a_fd.c +++ b/lib/s6a/s6a_fd.c @@ -42,7 +42,7 @@ int s6a_fd_init(const char *conffile) { CHECK_FCT_DO( s6a_config_apply(), goto error ); } - + /* Start the servers */ CHECK_FCT_DO( fd_core_start(), goto error ); diff --git a/src/s6a_auth.c b/src/s6a_auth.c index a3d2af8ada..39c234abf6 100644 --- a/src/s6a_auth.c +++ b/src/s6a_auth.c @@ -6,237 +6,199 @@ #include "s6a_auth.h" struct sess_state { - c_int32_t randval; /* a random value to store in Test-AVP */ - struct timespec ts; /* Time of sending the message */ + c_int32_t randval; /* a random value to store in Test-AVP */ + struct timespec ts; /* Time of sending the message */ } ; /* Cb called when an answer is received */ static void s6a_aia_cb(void * data, struct msg ** msg) { - struct sess_state * mi = NULL; - struct timespec ts; - struct session * sess; - struct avp * avp; - struct avp_hdr * hdr; - unsigned long dur; - int error = 0; - - CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), return ); + struct sess_state *mi = NULL; + struct timespec ts; + struct session *sess; + struct avp *avp; + struct avp_hdr *hdr; + unsigned long dur; + int error = 0; + + CHECK_SYS_DO(clock_gettime(CLOCK_REALTIME, &ts), return); - /* Search the session, retrieve its data */ - { - int new; - CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, *msg, &sess, &new), + /* Search the session, retrieve its data */ + { + int new; + CHECK_FCT_DO(fd_msg_sess_get(fd_g_config->cnf_dict, *msg, &sess, &new), return ); d_assert(new == 0, return, "fd_msg_sess_get() failed"); - - CHECK_FCT_DO( fd_sess_state_retrieve( s6a_mme_reg, sess, &mi ), + + CHECK_FCT_DO(fd_sess_state_retrieve( s6a_mme_reg, sess, &mi), return ); d_assert((void *)mi == data, return, "fd_sess_state_retrieve() failed"); - } - - /* Now log content of the answer */ - fprintf(stderr, "RECV "); - -#if 0 - /* Value of Test-AVP */ - CHECK_FCT_DO( fd_msg_search_avp ( *msg, s6a_avp, &avp), return ); - if (avp) { - CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return ); - if (hdr->avp_value->i32 == mi->randval) { - fprintf(stderr, "%x (%s) ", hdr->avp_value->i32, "Ok"); - } else { - fprintf(stderr, "%x (%s) ", hdr->avp_value->i32, "PROBLEM"); - error++; - } - } else { - fprintf(stderr, "no_Test-AVP "); - error++; - } -#endif - - /* Value of Result Code */ - CHECK_FCT_DO( fd_msg_search_avp ( *msg, s6a_result_code, &avp), - return ); - if (avp) { - CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return ); - d_info("Status: %d ", hdr->avp_value->i32); - if (hdr->avp_value->i32 != 2001) - error++; - } else { + } + + /* Value of Result Code */ + CHECK_FCT_DO(fd_msg_search_avp(*msg, s6a_result_code, &avp), return); + if (avp) + { + CHECK_FCT_DO(fd_msg_avp_hdr( avp, &hdr ), return); + if (hdr->avp_value->i32 != 2001) + error++; + } + else + { d_error("no_Result-Code"); - error++; - } - - /* Value of Origin-Host */ - CHECK_FCT_DO( fd_msg_search_avp ( *msg, s6a_origin_host, &avp), return ); - if (avp) { - CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return ); + error++; + } + + /* Value of Origin-Host */ + CHECK_FCT_DO(fd_msg_search_avp( *msg, s6a_origin_host, &avp), return); + if (avp) + { + CHECK_FCT_DO(fd_msg_avp_hdr( avp, &hdr ), return); d_info("From '%.*s' ", - (int)hdr->avp_value->os.len, hdr->avp_value->os.data); - } else { + (int)hdr->avp_value->os.len, hdr->avp_value->os.data); + } + else + { d_error("no_Origin-Host "); - error++; - } - - /* Value of Origin-Realm */ - CHECK_FCT_DO( fd_msg_search_avp ( *msg, s6a_origin_realm, &avp), return ); - if (avp) { - CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return ); + error++; + } + + /* Value of Origin-Realm */ + CHECK_FCT_DO(fd_msg_search_avp( *msg, s6a_origin_realm, &avp), return); + if (avp) + { + CHECK_FCT_DO(fd_msg_avp_hdr(avp, &hdr), return); d_info("('%.*s') ", - (int)hdr->avp_value->os.len, hdr->avp_value->os.data); - } else { + (int)hdr->avp_value->os.len, hdr->avp_value->os.data); + } + else + { d_error("no_Origin-Realm "); - error++; - } - - CHECK_POSIX_DO( pthread_mutex_lock(&s6a_config->stats_lock), ); - dur = ((ts.tv_sec - mi->ts.tv_sec) * 1000000) + + error++; + } + + CHECK_POSIX_DO(pthread_mutex_lock(&s6a_config->stats_lock),); + dur = ((ts.tv_sec - mi->ts.tv_sec) * 1000000) + ((ts.tv_nsec - mi->ts.tv_nsec) / 1000); - if (s6a_config->stats.nb_recv) { - /* Ponderate in the avg */ - s6a_config->stats.avg = (s6a_config->stats.avg * + if (s6a_config->stats.nb_recv) + { + /* Ponderate in the avg */ + s6a_config->stats.avg = (s6a_config->stats.avg * s6a_config->stats.nb_recv + dur) / (s6a_config->stats.nb_recv + 1); - /* Min, max */ - if (dur < s6a_config->stats.shortest) - s6a_config->stats.shortest = dur; - if (dur > s6a_config->stats.longest) - s6a_config->stats.longest = dur; - } else { - s6a_config->stats.shortest = dur; - s6a_config->stats.longest = dur; - s6a_config->stats.avg = dur; - } - if (error) - s6a_config->stats.nb_errs++; - else - s6a_config->stats.nb_recv++; - CHECK_POSIX_DO( pthread_mutex_unlock(&s6a_config->stats_lock), ); - - /* Display how long it took */ - if (ts.tv_nsec > mi->ts.tv_nsec) { + /* Min, max */ + if (dur < s6a_config->stats.shortest) + s6a_config->stats.shortest = dur; + if (dur > s6a_config->stats.longest) + s6a_config->stats.longest = dur; + } + else + { + s6a_config->stats.shortest = dur; + s6a_config->stats.longest = dur; + s6a_config->stats.avg = dur; + } + if (error) + s6a_config->stats.nb_errs++; + else + s6a_config->stats.nb_recv++; + CHECK_POSIX_DO( pthread_mutex_unlock(&s6a_config->stats_lock), ); + + /* Display how long it took */ + if (ts.tv_nsec > mi->ts.tv_nsec) d_info("in %d.%06ld sec", - (int)(ts.tv_sec - mi->ts.tv_sec), - (long)(ts.tv_nsec - mi->ts.tv_nsec) / 1000); - } else { + (int)(ts.tv_sec - mi->ts.tv_sec), + (long)(ts.tv_nsec - mi->ts.tv_nsec) / 1000); + else d_info("in %d.%06ld sec", - (int)(ts.tv_sec + 1 - mi->ts.tv_sec), - (long)(1000000000 + ts.tv_nsec - mi->ts.tv_nsec) / 1000); - } - - /* Free the message */ - CHECK_FCT_DO(fd_msg_free(*msg), return); - *msg = NULL; - - free(mi); - - return; + (int)(ts.tv_sec + 1 - mi->ts.tv_sec), + (long)(1000000000 + ts.tv_nsec - mi->ts.tv_nsec) / 1000); + + /* Free the message */ + CHECK_FCT_DO(fd_msg_free(*msg), return); + *msg = NULL; + + free(mi); + + return; } status_t s6_send_auth_req() { - struct msg * req = NULL; - struct avp * avp; - union avp_value val; - struct sess_state * mi = NULL, *svg; - struct session *sess = NULL; - - /* Create the request */ - CHECK_FCT_DO( fd_msg_new( s6a_cmd_air, - MSGFL_ALLOC_ETEID, &req ), goto out ); - - /* Create a new session */ - #define TEST_APP_SID_OPT "app_s6a" - CHECK_FCT_DO( fd_msg_new_session( req, (os0_t)TEST_APP_SID_OPT, - CONSTSTRLEN(TEST_APP_SID_OPT) ), goto out ); - CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, req, &sess, NULL), - goto out ); - - /* Create the random value to store with the session */ - mi = malloc(sizeof(struct sess_state)); + struct msg *req = NULL; + struct avp *avp; + union avp_value val; + struct sess_state *mi = NULL, *svg; + struct session *sess = NULL; + + /* Create the request */ + CHECK_FCT_DO(fd_msg_new( s6a_cmd_air, + MSGFL_ALLOC_ETEID, &req ), goto out); + + /* Create a new session */ + #define S6A_APP_SID_OPT "app_s6a" + CHECK_FCT_DO(fd_msg_new_session(req, (os0_t)S6A_APP_SID_OPT, + CONSTSTRLEN(S6A_APP_SID_OPT)), goto out); + CHECK_FCT_DO(fd_msg_sess_get(fd_g_config->cnf_dict, req, &sess, NULL), + goto out); + + /* Create the random value to store with the session */ + mi = malloc(sizeof(struct sess_state)); d_assert(mi, goto out, "malloc failed: %s", strerror(errno)); - - mi->randval = (int32_t)random(); - - /* Now set all AVPs values */ - - /* Set the Destination-Realm AVP */ - { - CHECK_FCT_DO( fd_msg_avp_new ( s6a_destination_realm, 0, &avp ), - goto out ); - val.os.data = (unsigned char *)(s6a_config->dest_realm); - val.os.len = strlen(s6a_config->dest_realm); - CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); - CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), - goto out ); - } - - /* Set the Destination-Host AVP if needed*/ - if (s6a_config->dest_host) { - CHECK_FCT_DO( fd_msg_avp_new ( s6a_destination_host, 0, &avp ), - goto out ); - val.os.data = (unsigned char *)(s6a_config->dest_host); - val.os.len = strlen(s6a_config->dest_host); - CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); - CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), - goto out ); - } - - /* Set Origin-Host & Origin-Realm */ - CHECK_FCT_DO( fd_msg_add_origin ( req, 0 ), goto out ); - - /* Set the User-Name AVP if needed*/ - if (s6a_config->user_name) { - CHECK_FCT_DO( fd_msg_avp_new ( s6a_user_name, 0, &avp ), goto out ); - val.os.data = (unsigned char *)(s6a_config->user_name); - val.os.len = strlen(s6a_config->user_name); - CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); - CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), - goto out ); - } + + mi->randval = (int32_t)random(); + + /* Set the Destination-Realm AVP */ + CHECK_FCT_DO(fd_msg_avp_new(s6a_destination_realm, 0, &avp), goto out); + val.os.data = (unsigned char *)(fd_g_config->cnf_diamrlm); + val.os.len = strlen(fd_g_config->cnf_diamrlm); + CHECK_FCT_DO(fd_msg_avp_setvalue(avp, &val), goto out); + CHECK_FCT_DO(fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out); + + /* Set Origin-Host & Origin-Realm */ + CHECK_FCT_DO(fd_msg_add_origin(req, 0), goto out); + + /* Set the User-Name AVP if needed*/ + #define S6A_USER_NAME "01045238277" + CHECK_FCT_DO(fd_msg_avp_new(s6a_user_name, 0, &avp), goto out); + val.os.data = (unsigned char *)(S6A_USER_NAME); + val.os.len = strlen(S6A_USER_NAME); + CHECK_FCT_DO(fd_msg_avp_setvalue(avp, &val), goto out); + CHECK_FCT_DO(fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out); - /* Set the Auth-Session-Statee AVP if needed*/ - { - CHECK_FCT_DO( fd_msg_avp_new ( s6a_auth_session_state, 0, &avp ), - goto out ); - val.i32 = 1; - CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); - CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), - goto out ); - } + /* Set the Auth-Session-Statee AVP if needed*/ + CHECK_FCT_DO(fd_msg_avp_new(s6a_auth_session_state, 0, &avp), goto out); + val.i32 = 1; + CHECK_FCT_DO(fd_msg_avp_setvalue(avp, &val), goto out); + CHECK_FCT_DO(fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out); - /* Set the Visited-PLMN-Id AVP if needed*/ - { - c_uint8_t plmn[3] = { 0x00, 0xf1, 0x10 }; - CHECK_FCT_DO( fd_msg_avp_new ( s6a_visited_plmn_id, 0, &avp ), - goto out ); - val.os.data = plmn; - val.os.len = 3; - CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); - CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), - goto out ); - } - - CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &mi->ts), goto out ); - - /* Keep a pointer to the session data for debug purpose, in real life we would not need it */ - svg = mi; - - /* Store this value in the session */ - CHECK_FCT_DO( fd_sess_state_store ( s6a_mme_reg, sess, &mi ), goto out ); - - /* Log sending the message */ - d_info("SEND %x to '%s' (%s)\n", svg->randval, - s6a_config->dest_realm, s6a_config->dest_host?:"-" ); - - /* Send the request */ - CHECK_FCT_DO( fd_msg_send( &req, s6a_aia_cb, svg ), goto out ); + /* Set the Visited-PLMN-Id AVP if needed*/ + c_uint8_t plmn[3] = { 0x00, 0xf1, 0x10 }; + CHECK_FCT_DO(fd_msg_avp_new(s6a_visited_plmn_id, 0, &avp), goto out); + val.os.data = plmn; + val.os.len = 3; + CHECK_FCT_DO(fd_msg_avp_setvalue(avp, &val ), goto out); + CHECK_FCT_DO(fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out); + + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &mi->ts), goto out ); + + /* Keep a pointer to the session data for debug purpose, + * in real life we would not need it */ + svg = mi; + + /* Store this value in the session */ + CHECK_FCT_DO(fd_sess_state_store(s6a_mme_reg, sess, &mi), goto out); + + /* Log sending the message */ + d_info("SEND %x to '%s' (-)\n", svg->randval, fd_g_config->cnf_diamrlm); + + /* Send the request */ + CHECK_FCT_DO(fd_msg_send(&req, s6a_aia_cb, svg), goto out); - /* Increment the counter */ - CHECK_POSIX_DO( pthread_mutex_lock(&s6a_config->stats_lock), ); - s6a_config->stats.nb_sent++; - CHECK_POSIX_DO( pthread_mutex_unlock(&s6a_config->stats_lock), ); + /* Increment the counter */ + CHECK_POSIX_DO( pthread_mutex_lock(&s6a_config->stats_lock), ); + s6a_config->stats.nb_sent++; + CHECK_POSIX_DO( pthread_mutex_unlock(&s6a_config->stats_lock), ); out: - return CORE_OK; + return CORE_OK; }