implementing an extension for freediameter n.
Skip this Video
Loading SlideShow in 5 Seconds..
Implementing an extension for freeDiameter PowerPoint Presentation
Download Presentation
Implementing an extension for freeDiameter

Loading in 2 Seconds...

  share
play fullscreen
1 / 35
Download Presentation

Implementing an extension for freeDiameter - PowerPoint PPT Presentation

mendel
931 Views
Download Presentation

Implementing an extension for freeDiameter

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

  1. Implementing an extension for freeDiameter SouheilBen Ayed (Keio) SebastienDecugis (NICT) FreeDiameter Extension WIDE AAA-WG

  2. FreeDiameter Extension Tutorial • Goal : Introduce on writing an Extension for freeDiameter • Tutorial based on “test_app” extension • Tutorial includes: • Writing an Extension • start writing an extension • Add object definition to Dictionary • Manage diameter messages and AVPs • Manage sessions • Configuring an extension for freeDiameter • Add Extension to freeDiameter • Add/edit CMAKE configuration files • Add Extension to be loaded. • Build/test Souheil Ben Ayed, Sebastien Decugis

  3. Steps :writing an Extension for freeDiameter • Start writing your extension • Includes, Entry point function, Cleanup callback function • Add new objects to Dictionary • Application object , commands objects , AVPs objects, rules … • Add application to be announced (CER/CEA exchange) • Manage Messages and AVPs • Create Request/Response messages, send message … • Add AVPs to message, set AVP Data, search for AVPs … • Manage Sessions • Create new session, store/retrieve session state, destroy session • Add your extension to freeDiameter • Edit freeDiameter configuration, Cmake configuration Souheil Ben Ayed, Sebastien Decugis

  4. Writing an extension Start writing an extension Adding objects to dictionary Manage Messages and AVPs Manage Sessions Souheil Ben Ayed, Sebastien Decugis

  5. Start writing your extension • Extension header file: • freeDiameter API #include <freeDiameter/extension.h> static intta_entry(char * conffile); EXTENSION_ENTRY("test_app", ta_entry); /* Entry point */ static intta_entry(char * conffile) { TRACE_ENTRY("%p", conffile); return 0; } /* Cleanup callback*/ voidfd_ext_fini(void) { return ; /* Extension is terminated */ } • Define the entry point • Entry point called when loading the extension • Function called when the freeDiameter daemon exits Souheil Ben Ayed, Sebastien Decugis

  6. Add Objects to the Dictionary • /* A simple object: the test application */ • structdict_object * ta_appli = NULL; • structdict_application_dataappdata = { • /*application_id =*/ 999999, • /* application_name =*/ "Test application" • }; • ret = fd_dict_new( • dict, /* the dictionary we are adding into */ • DICT_APPLICATION, • &appdata, • NULL, /* parent: optional (vendor in this case) */ • &ta_appli • ); • /* Don’tforget to check the value of ret … */ • Object reference • The data of the new object • The new application is defined in “dict” upon success. Souheil Ben Ayed, Sebastien Decugis

  7. Search in Dictionary (fd_dict_search) - 1 • The function fd_dict_search is : • Look for an application, command, AVP, vendor object… • Check if an object is in the dictionary. • dict : Target dictionary • type : Type of object that is looking for: DICT_APPLICATION, DICT_AVP,… • criteria: How to search for the object: APPLICATION_BY_NAME, AVP_BY_NAME, AVP_BY_CODE,… • what : value of the criteria to match intfd_dict_search ( structdictionary * dict, enumdict_object_type type, int criteria, void * what, structdict_object **result, intretval ); Souheil Ben Ayed, Sebastien Decugis

  8. Search in Dictionary (fd_dict_search) - 2 • To search for an object: • Creates a dict_object : where the object will be store in. • What is the type of the object : • DICT_APPLICATION • Choose your criteria for searching (+the value for this criteria): • APPLICATION_BY_NAME • Now we are ready to search for an object corresponding to this criteria in the dictionary. structdict_object * appli, * avp_username; command_code_t code = 268; fd_dict_search(dict, DICT_APPLICATION, APPLICATION_BY_NAME, " Test application", &appli, ENOENT); fd_dict_search(dict, DICT_AVP, AVP_BY_CODE, &code, &avp_username, ENOENT); Souheil Ben Ayed, Sebastien Decugis

  9. Register application for advertising • To register an application to be advertized in CER/CEA exchanges. • Example: intfd_disp_app_support ( structdict_object * app, structdict_object * vendor, int auth, int acct ); structdict_object* ta_appli = NULL; structdict_object* ta_vendor = NULL; application_id_tappli_id = 999999; /*search Application object by application ID*/ fd_dict_search(fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_ID, &appli_id, & ta_appli, ENOENT); /*search vendor object*/ fd_dict_search(fd_g_config->cnf_dict, DICT_VENDOR, VENDOR_OF_APPLICATION, &ta_appli, & ta_vendor, ENOENT); /* Advertise the support for the test application in the peer */ fd_disp_app_support ( ta_appli, ta_vendor, 1, 0 ) ; Souheil Ben Ayed, Sebastien Decugis

  10. Register a callback function - 1 • This callback will be called when a message matching criteria is received by freeDiameter daemon. • To match criteria. • APP ID, Command code, AVP code, … • And give the value to match. • Example: • Command code criteria (DISP_HOW_CC). • And for messages with: • Application Id = 5, • Command code = 268 structdisp_when { structdict_object *app; structdict_object *command; structdict_object *avp; structdict_object *value; }; enumdisp_how { DISP_HOW_ANY = 1, DISP_HOW_APPID, DISP_HOW_CC, DISP_HOW_AVP, DISP_HOW_AVP_ENUMVAL }; Souheil Ben Ayed, Sebastien Decugis

  11. Register a callback function - 2 • To register a callback function : • Example: intfd_disp_register ( int (*cb)( structmsg **, structavp *, struct session *, enumdisp_action *), enumdisp_how how, structdisp_when * when, structdisp_hdl ** handle ); /* intta_tr_cb(structmsg **, structavp *, struct session *, enumdisp_action *); */ staticstructdisp_hdl * ta_hdl_tr = NULL; /* handler for Test-Request reqcb */ structdisp_when data; data.app = ta_appli; data.command = ta_cmd_r; fd_disp_register( ta_tr_cb, DISP_HOW_CC, &data, &ta_hdl_tr ) ; Souheil Ben Ayed, Sebastien Decugis

  12. “test_app” extension entry point Souheil Ben Ayed, Sebastien Decugis

  13. Manage Diameter Messages • A message object is made of a header and 0 or more AVPs. • Structure of message header: • Dump a message structmsg_hdr { uint8_tmsg_version; uint32_tmsg_length; uint8_tmsg_flags; command_code_tmsg_code; application_id_tmsg_appl; uint32_tmsg_hbhid; uint32_tmsg_eteid; }; Message AVP Grp. AVP AVP AVP AVP • /*Dump the content of message object recursively*/ • voidfd_msg_dump_walk ( int level, msg_or_avp *obj ); • /*Dump only the content of message object itself */ • voidfd_msg_dump_one ( int level, msg_or_avp *obj ); Souheil Ben Ayed, Sebastien Decugis

  14. New request Diameter Message • fd_msg_newcreates a new empty Diameter message from a request command template. • model : corresponding to an object from dictionary. • flags : options to create message ( combination of MSGFL_*) • msg : the new created message • Example : • intfd_msg_new ( structdict_object * model, int flags, structmsg ** msg ); structmsg * req; structdict_object * ta_cmd_r; command_code_t code = 257; /*Search request command object by command code “257” */ fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_CODE_R,& code, &ta_cmd_r); /*Create new request message with command code “257” and an end-to-end Id*/ fd_msg_new( ta_cmd_r, MSGFL_ALLOC_ETEID, &req ); Souheil Ben Ayed, Sebastien Decugis

  15. New response Diameter Message • fd_msg_new_answer_from_req creates an empty answer message corresponding to a request. • R flag cleared • Command code, application id, hop-by-hop id and end-to-end id are added in the new message. • The session Id AVP is copied if present in request. • Or creates a new empty response message (with answer command model /CMD_BY_CODE_A). • Intfd_msg_new_answer_from_req ( structdictionary * dict, structmsg ** msg, int flag ); fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ); fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_CODE_A,& code, &ta_cmd_a); /*Create new request message with command code “257” and an end-to-end Id*/ fd_msg_new( ta_cmd_a, NULL, &ans ); Souheil Ben Ayed, Sebastien Decugis

  16. Send Diameter message • Both request and response messages are sent on network using fd_msg_send function. • When sending message, a callback function may be specified for receiving the answer message. • Example: intfd_msg_send ( structmsg ** pmsg, void (*anscb)(void *, structmsg **), void * data ); /*send answer message */ fd_msg_send( &ans, NULL, NULL ); /*send a request message with answer callback */ fd_msg_send( &req, ta_cb_ans, sdata); Souheil Ben Ayed, Sebastien Decugis

  17. AVPs • AVPs are part of a message structure. • Some AVPs can contain other AVPs: Grouped AVPs AVP header structure structavp_hdr { avp_code_tavp_code; uint8_tavp_flags; uint32_tavp_len; vendor_id_tavp_vendor; unionavp_value * avp_value; }; AVP value unionavp_value { struct { uint8_t *data; /*bytes buffer*/ size_tlen; } os; int32_t i32;/* integer 32 */ int64_t i64;/* integer 64 */ uint32_t u32;/* unsigned 32 */ uint64_t u64;/* unsigned 64 */ float f32;/* float 32 */ double f64;/* float 64 */ }; Souheil Ben Ayed, Sebastien Decugis

  18. Create AVP, set value and add to message-1 • fd_msg_avp_new creates a new AVP. • fd_msg_avp_setvalue set AVP value . • To add an AVP to a message or an AVP to an other AVP: • reference: a message or AVP object • dir : location where to insert this AVP • MSG_BRW_FIRST_CHILD, MSG_BRW_LAST_CHILD, MSG_BRW_NEXT, MSG_BRW_PREV,… • avp: an AVP to insert. intfd_msg_avp_new ( structdict_object * model, int flags, structavp ** avp ); intfd_msg_avp_setvalue ( structavp *avp, unionavp_value *value ); intfd_msg_avp_add ( msg_or_avp * reference, enummsg_brw_dir dir, structavp *avp); Souheil Ben Ayed, Sebastien Decugis

  19. Create AVP, set value and add to message-2 strcutavp* avp; structmsg* req; intrandval; unsignedchar* username; unionavp_valueval; structdict_object * ta_user_name, *ta_avp; … { fd_msg_avp_new ( ta_user_name, 0, &avp ); val.os.data = (unsignedchar *)(user_name); val.os.len = strlen(user_name); fd_msg_avp_setvalue( avp, &val ); fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ); } { fd_msg_avp_new ( ta_avp, 0, &avp ); val.i32 = mi->randval; fd_msg_avp_setvalue( avp, &val ); fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ); } /* Set the User-Name AVP if needed*/ /* Set the Test-AVP AVP */ Souheil Ben Ayed, Sebastien Decugis

  20. Others functions • To add Origin-Host AVP and Origin-Realm AVP: • If osi is set add the Origin-State-Id AVP at the end of the message. • To add Result-Code AVP. • If optavp is provided, a Failed AVP will be added to the message with the optavp content inside it. • To search an AVP in a message: intfd_msg_add_origin ( structmsg * msg, intosi ); intfd_msg_rescode_set( structmsg * msg, char * rescode, char * errormsg, structavp * optavp, inttype_id ); intfd_msg_search_avp ( structmsg * msg, structdict_object * what, structavp ** avp ); Souheil Ben Ayed, Sebastien Decugis

  21. Retrieve AVP header and get AVP value • With fd_msg_avp_hdr we can retrieve the header of an AVP. • From AVP header we can get stored AVP value. (stored value depends on value type) structavp * avp; structdict_object * ta_avp; structavp_hdr * hdr; … fd_msg_search_avp ( *msg, ta_avp, &avp); if (avp) { fd_msg_avp_hdr( avp, &hdr ); printf("%x (%s) ", hdr->avp_value->i32, (hdr->avp_value->i32 == mi->randval) ? "Ok" : "PROBLEM"); } else { printf("no_Test-AVP "); } Souheil Ben Ayed, Sebastien Decugis

  22. Receive message (server side) Souheil Ben Ayed, Sebastien Decugis

  23. Manage Sessions -1 • Only one session objectfor each session-Id AVP. • To associate a state with a session object we must first register a handler for sessions. struct session { inteyec; char *sid; uint32_t hash; structfd_listchain_h structtimespec timeout; structfd_list expire; pthread_mutex_tstlock; structfd_liststates; intmsg_cnt; }; Souheil Ben Ayed, Sebastien Decugis

  24. Manage Sessions -2 • To create a session object : fd_sess_new. • A Session-Id string is generated. • opt : is optional string to be concatenated to the identifier. • fd_sess_destroydestroys a session and all associated data. • Destroying a session is equivalent to a session timeout expired. intfd_sess_new ( structsession ** session, char * diamId, char * opt, size_toptlen ); intfd_sess_destroy ( structsession ** session ); Souheil Ben Ayed, Sebastien Decugis

  25. Manage Sessions -3 • We can retrieve a session object from a Session-Id string. • Retrieve the session identifier of a session object. • Modify the timeout for a session object. intfd_sess_getsid ( structsession * session, char ** sid ); intfd_sess_fromsid ( char * sid, size_tlen, structsession ** session, int * new); intfd_sess_settimeout( structsession * session, conststructtimespec * timeout ); Souheil Ben Ayed, Sebastien Decugis

  26. Session handler • To associate a state with a Session-Id we must first create a handler for sessions. • handler : the handler for sessions. • cleanup : a callback function that must be called when the session with associated data is destroyed. • This session handler should be destroyed at the cleanup callback. intfd_sess_handler_create( structsession_handler ** handler, void (*cleanup)(char * sid, session_state * state)) intfd_sess_handler_destroy( structsession_handler ** handler) Souheil Ben Ayed, Sebastien Decugis

  27. Save/Retrieve session’s state • To store a state with a session: fd_sess_state_store • To retrieve the saved state for a session: fd_sess_state_retrieve • Retrieving stored state implies disassociating the state with the session. • Use fd_sess_state_store to associate the new state with the session. intfd_sess_state_store( structsession_handler * handler, structsession * session, session_state ** state); intfd_sess_state_retrieve( structsession_handler * handler, structsession * session, session_state ** state); Souheil Ben Ayed, Sebastien Decugis

  28. Using sessions and session handler - 1 staticstructsession_handler * ta_cli_reg = NULL; /*session handler*/ structsession *sess ; fd_sess_handler_create(&ta_cli_reg, free); …. • /* Create a new session */ • fd_sess_new( &sess, fd_g_config->cnf_diamid, "app_test", 8 ); • /* Session-Id */ { • char * sid; • fd_sess_getsid ( sess, &sid ); • fd_msg_avp_new ( ta_sess_id, 0, &avp ); • val.os.data = sid; • val.os.len = strlen(sid); • fd_msg_avp_setvalue( avp, &val ); • fd_msg_avp_add( req, MSG_BRW_FIRST_CHILD, avp ); • } • /* Store the value of mi in the session */ • fd_sess_state_store ( ta_cli_reg, sess, &mi ); Souheil Ben Ayed, Sebastien Decugis

  29. Using sessions and session handler - 2 /* Search the session, retrieve its data */ { int new; fd_msg_sess_get(fd_g_config->cnf_dict, *msg, &sess, &new); fd_sess_state_retrieve( ta_cli_reg, sess, &mi ); } … voidfd_ext_fini( void) { … (void) fd_sess_handler_destroy(&ta_cli_reg); … }; Souheil Ben Ayed, Sebastien Decugis

  30. Send/Receive message ( client side) Souheil Ben Ayed, Sebastien Decugis

  31. Add an extension to freeDiameter Add Extension Add/edit CMAKE configuration files Add Extension to be loaded. Build/test Souheil Ben Ayed, Sebastien Decugis

  32. Add your Extension • Make sure that you have Cmake installed. • Add your extension to freeDiameter extensions. • Add the extension to be built with freeDiameter (freeDiameter_path\extensions\CMakeList.txt) • # Create an option “BUILD_TEST_APP” set to ON • OPTION(BUILD_TEST_APP "Build test_app.fdx? (Test application)"ON) • #If the “BUILD_TEST_APP” is set add the extension directory to be built • IF (BUILD_TEST_APP) • SUBDIRS (test_app) • ENDIF (BUILD_TEST_APP) Souheil Ben Ayed, Sebastien Decugis

  33. Create a CMakeFile for your extension • Add a CMakeList.txt file to the extension. • Example : (CMakeList.txt for test_app) # The Test Diameter Application extension PROJECT("Test Diameter Application" C) # Parser files BISON_FILE(ta_conf.y) FLEX_FILE(ta_conf.l) SET_SOURCE_FILES_PROPERTIES(lex.ta_conf.cta_conf.tab.c PROPERTIES COMPILE_FLAGS "-I ${CMAKE_CURRENT_SOURCE_DIR}") # List of source files SET( APP_TEST_SRC test_app.htest_app.clex.ta_conf.cta_conf.tab.cta_conf.tab.hta_sig.cta_dict.cta_cli.cta_serv.c ) # Compile as a module FD_ADD_EXTENSION(test_app${APP_TEST_SRC}) Souheil Ben Ayed, Sebastien Decugis

  34. Add extension to be loaded and build • Add extension to be loaded by freeDiameter daemon, (freeDiameterconfigurationfile) • Then generate Makefiles and Build: • cmake command or cmake-gui # Extension without configuration file LoadExtension = "extensions/test_app.fdx"; # Extension with a configuration file LoadExtension = "extensions/test_app.fdx":" extensions/test_app/test_app.conf"; Souheil Ben Ayed, Sebastien Decugis

  35. Questions ??? Next >>> Demonstration Souheil Ben Ayed, Sebastien Decugis