Navigation


Changeset 640:237cf6339546 in freeDiameter


Ignore:
Timestamp:
Dec 20, 2010 7:36:40 PM (2 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Message:

dbg_interactive almost complete

Files:
2 added
10 edited

Legend:

Unmodified
Added
Removed
  • doc/dbg_interactive.py.sample

    r639 r640  
    9090l1.concat(l3)        # l1 -> l2 -> l5 -> l4 
    9191 
    92 elements = l1.enum_as()  # default: enumerates as fd_list. Warning: this a copy, changing the python list has no effect on the underlying list. 
     92elements = l1.enum_as()  # default: enumerates as fd_list. Warning: this a copy, changing the python list has no effect on the underlying fd_list. 
    9393for li in elements: 
    9494  li.dump() 
     
    224224del r 
    225225 
    226 d.dump() 
    227 del d 
    228  
    229226r2 = dict_rule_data(my_avp_int, RULE_REQUIRED) # min & max are optional parameters, default to -1 
    230227r3 = dict_rule_data(my_avp_int, RULE_REQUIRED, 2, 3) # min is 2, max is 3 
     
    234231del r4 
    235232 
     233d.dump() 
     234del d 
     235 
    236236####### Now play with the "real" dictionary 
    237237 
     
    273273s1.getsid() 
    274274s2 = session("this.is.a.full.session.id") 
    275 r,s3,isnew = fd_sess_fromsid("this.is.a.full.session.id") 
     275r,s3,isnew = fd_sess_fromsid("this.is.a.full.session.id")  # use this call if "isnew" is really needed... 
    276276s4 = session("host.id", "optional.part") 
    277277s4.settimeout(30) # the python wrapper takes a number of seconds as parameter for simplicity 
     
    304304  print "%s (%s): %s" % (c.diamid, c.realm, c.score) 
    305305 
     306del rd 
     307 
     308 
     309# A rt_fwd callback has the following prototype: 
     310def my_rtfwd_cb(msg): 
     311    print "Forwarding the following message:" 
     312    msg.dump() 
     313    return [ 0, msg ]  # return None instead of msg to stop forwarding. 
     314 
     315fwdhdl = fd_rt_fwd_hdl( my_rtfwd_cb, RT_FWD_REQ ) 
     316 
     317 
     318# A rt_out cb has the following prototype: 
     319def my_rtout_cb(msg, list): 
     320    print "Sending out the following message:" 
     321    msg.dump() 
     322    print "The possible candidates are:" 
     323    for c in list.enum_as("struct rtd_candidate *"): 
     324       print "%s (%s): %s" % (c.diamid, c.realm, c.score) 
     325    return 0   # returns an error code (standard errno values) 
     326 
     327outhdl = fd_rt_out_hdl( my_rtout_cb )  # a priority can be specified as 2nd parameter, default is 0. 
     328 
     329 
     330 
    306331 
    307332 
     
    322347val = avp_value() 
    323348val.u32 = 123 
    324 vi.setval(None)  # this cleans a previous value (not needed) 
     349vi.setval(None)  # this cleans a previous value (usually not needed) 
    325350vi.setval(val) 
    326351val.os = "my.origin.host" 
     
    379404dwr.children() 
    380405# example use: 
    381 for a in dwr.children() 
     406for a in dwr.children(): 
    382407  a.dump(0)  # 0 means: dump only this object, do not walk the tree 
    383408 
     
    436461 
    437462# Send a message: 
     463mydwr = msg(buf) 
    438464mydwr.send() 
    439465 
     
    447473    return None 
    448474 
     475mydwr = msg(buf) 
    449476mydwr.send(send_callback, some_object) 
    450477 
    451478 
    452479# Set a result code in an answer message. 
     480mydwr = msg(buf) 
    453481dwa = mydwr.create_answer() 
    454482dwa.rescode_set()   # This adds the DIAMETER_SUCCESS result code 
     
    598626myqueue.length() 
    599627 
     628 
     629## Variants: 
     630# All the previous calls are suitable to queue Python objects. 
     631# In order to interact with objects queued / poped by C counterpart, 
     632# a second parameter must be passed to specify the object type, 
     633# as follow: 
     634ev = fd_event() 
     635ev.code = FDEV_DUMP_EXT 
     636cvar.fd_g_config.cnf_main_ev.post(ev, "struct fd_event *") 
     637 
     638# Similarly, for *get, we can specify the structure that was queued: 
     639myqueue.get("struct fd_event *") 
     640myqueue.tryget("struct fd_event *") 
     641myqueue.timedget(3, "struct fd_event *") 
     642 
    600643del myqueue 
    601644 
     
    614657np = peer_info() 
    615658np.pi_diamid = "nas.localdomain" 
    616 np.config.pic_flags.pro4 = 1   # 1 for TCP, for some reason PI_P4_TCP is not defined 
    617  
    618  
     659np.config.pic_flags.pro4 = PI_P4_TCP 
    619660 
    620661 
     
    634675        print "The peer has been destroyed before it completed the connection." 
    635676 
    636 # Then add the peer simply like this: 
     677# Then add the peer like this: 
    637678np.add(add_cb) 
    638679 
    639680 
     681# Search a peer by its diameter id (returns a peer_hdr object if found) -- similar to fd_peer_getbyid 
     682p = peer_search("nas.domain.aaa") 
     683 
     684 
     685## Validation callback (see fd_peer_validate_register documentation) 
     686 
     687# cb2 prototype: 
     688def my_validate_cb2(pinfo): 
     689    print "Cb2 callback trigged for peer %s" % (pinfo.pi_diamid) 
     690    # Usually, this would be used only to check some TLS properties,  
     691    # which is not really possible yet through the python interpreter... 
     692    return 0   # return an error code if the peer is not validated 
     693 
     694# cb prototype: 
     695def my_validate_cb(pinfo): 
     696    print "Validate callback trigged for peer %s" % (pinfo.pi_diamid) 
     697    # If the peer is not allowed to connect: 
     698    #return -1 
     699    # If the peer is authorized: 
     700    #return 1 
     701    # In addition, if IPsec is allowed, 
     702    #pinfo.config.pic_flags.sec = PI_SEC_NONE 
     703    # If no decision has been made: 
     704    #return 0 
     705    # If the peer is temporarily authorized but a second callback must be called after TLS negociation: 
     706    return my_validate_cb2 
     707 
     708# Register the callback, it will be called on new incoming connections. 
     709peer_validate_register(my_validate_cb) 
     710 
     711 
     712 
     713############# ENDPOINTS ############ 
     714 
     715ep = fd_endpoint("129.168.168.192") 
     716 
     717# with port: 
     718ep = fd_endpoint("129.168.168.192", 3868) 
     719 
     720# With different flags: 
     721ep = fd_endpoint("129.168.168.192", 3868, EP_FL_PRIMARY) 
     722 
     723# Add IP information for the peer 
     724np = peer_info() 
     725ep.add_merge(np.pi_endpoints) 
     726fd_ep_dump(0, np.pi_endpoints) 
     727 
     728 
  • extensions/dbg_interactive/CMakeLists.txt

    r637 r640  
    2626        queues.i 
    2727        peers.i 
     28        events.i 
     29        endpoints.i 
    2830        ) 
    2931SET_SOURCE_FILES_PROPERTIES(dbg_interactive.i PROPERTIES SWIG_MODULE_NAME fDpy) 
  • extensions/dbg_interactive/dbg_interactive.i

    r638 r640  
    6868static int wrapper_errno; 
    6969static PyObject* wrapper_errno_py; 
    70 static char * wrapper_error_txt; /* if NULL, use strerror(errno) */ 
     70static const char * wrapper_error_txt; /* if NULL, use strerror(errno) */ 
    7171#define DI_ERROR(code, pycode, str) {   \ 
    7272        fd_log_debug("[dbg_interactive] ERROR: %s: %s\n", __PRETTY_FUNCTION__, str ? str : strerror(code)); \ 
     
    8888        /* Now, test for error */ 
    8989        if (wrapper_errno) { 
    90                 char * str = wrapper_error_txt ? wrapper_error_txt : strerror(wrapper_errno); 
     90                const char * str = wrapper_error_txt ? wrapper_error_txt : strerror(wrapper_errno); 
    9191                PyObject * exc = wrapper_errno_py; 
    9292                if (!exc) { 
     
    109109 ***********************************/ 
    110110 
    111 %apply (char *STRING, size_t LENGTH) { ( char * string, size_t len ) }; /* fd_hash */ 
     111%apply (char *STRING, size_t LENGTH) { ( char * string, size_t len ) }; 
    112112 
    113113/* Generic typemap for functions that create something */ 
     
    119119} 
    120120 
     121/* Typemap to return a boolean value as output parameter */ 
     122%typemap(in, numinputs=0,noblock=1) int * BOOL_OUT (int temp) { 
     123        $1 = &temp; 
     124} 
     125%typemap(argout,noblock=1) int * BOOL_OUT { 
     126        PyObject * r; 
     127        if (*$1) 
     128                r = Py_True; 
     129        else 
     130                r = Py_False; 
     131        Py_XINCREF(r); 
     132        %append_output(r); 
     133} 
     134 
    121135/* To allow passing callback functions defined in python */ 
    122136%typemap(in) PyObject *PyCb { 
    123         if (!PyCallable_Check($input)) { 
    124                 PyErr_SetString(PyExc_TypeError, "Need a callable object!"); 
    125                 SWIG_fail; 
     137        if (!$input || ($input == Py_None)) { 
     138                $1 = NULL; 
     139        } else { 
     140                if (!PyCallable_Check($input)) { 
     141                        PyErr_SetString(PyExc_TypeError, "Need a callable object!"); 
     142                        SWIG_fail; 
     143                } 
     144                $1 = $input; 
    126145        } 
    127         $1 = $input; 
    128146} 
    129147 
    130  
     148%{ 
    131149/* Forward declaration for the peers module */ 
    132 %{ 
    133150static void fd_add_cb(struct peer_info *peer, void *data); 
    134151%} 
     152 
     153/* Overwrite declaration to apply typemaps */ 
     154int fd_sess_fromsid ( char * STRING, size_t LENGTH, struct session ** OUTPUT, int * BOOL_OUT); 
     155 
    135156 
    136157/********************************************************* 
     
    155176 
    156177%include "peers.i" 
     178%include "events.i" 
     179%include "endpoints.i" 
  • extensions/dbg_interactive/lists.i

    r637 r640  
    7171        } 
    7272        /* Test for emptyness */ 
    73         int isempty() { 
    74                 return FD_IS_LIST_EMPTY($self); 
     73        PyObject * isempty() { 
     74                PyObject * ret; 
     75                if (FD_IS_LIST_EMPTY($self)) 
     76                        ret = Py_True; 
     77                else 
     78                        ret = Py_False; 
     79                Py_XINCREF(ret); 
     80                return ret; 
    7581        } 
    7682        /* Concatenate two lists */ 
  • extensions/dbg_interactive/messages.i

    r638 r640  
    293293         
    294294        /* Is routable? */ 
    295         int is_routable() { 
    296                 return fd_msg_is_routable($self); 
     295        PyObject * is_routable() { 
     296                PyObject * r; 
     297                if (fd_msg_is_routable($self)) 
     298                        r = Py_True; 
     299                else 
     300                        r = Py_False; 
     301                Py_XINCREF(r); 
     302                return r; 
    297303        } 
    298304         
  • extensions/dbg_interactive/peers.i

    r638 r640  
    6767 
    6868%extend peer_info { 
     69        peer_info () { 
     70                struct peer_info *np = (struct peer_info *)calloc(1, sizeof(struct peer_info)); 
     71                if (!np) { 
     72                        DI_ERROR_MALLOC; 
     73                        return NULL; 
     74                } 
     75                 
     76                fd_list_init(&np->pi_endpoints, NULL); 
     77                 
     78                return np; 
     79        } 
     80 
    6981        /* Wrapper around fd_peer_add to allow calling the python callback */ 
     82        %delobject add; 
    7083        void add(PyObject * PyCb=NULL) { 
    7184                int ret; 
     
    8194                } 
    8295        } 
    83  
    84         /* Add an endpoint */ 
    85         void add_endpoint(char * endpoint) { 
    86                 fd_log_debug("What is the best way in python to pass an endpoint? (ip + port)"); 
    87         } 
    88  
    89 } 
     96} 
     97 
     98%inline %{ 
     99static struct peer_hdr * peer_search(char *diamid) { 
     100        struct peer_hdr *r = NULL; 
     101        int ret = fd_peer_getbyid( diamid, &r ); 
     102        if (ret) { 
     103                DI_ERROR(ret, NULL, NULL); 
     104                return NULL; 
     105        } 
     106        return r; 
     107} 
     108%} 
     109 
     110%{ 
     111static PyObject * validate_cb_py = NULL; 
     112static PyObject * validate_cb2_py = NULL; 
     113 
     114/* C wrapper that calls validate_cb2_py */ 
     115int call_the_python_validate_callback2(struct peer_info * info) { 
     116        PyObject *PyInfo; 
     117        PyObject *result = NULL; 
     118        int ret = 0; 
     119         
     120        if (!validate_cb2_py) { 
     121                fd_log_debug("Internal error: missing the callback2!\n"); 
     122                return ENOTSUP; 
     123        } 
     124         
     125        SWIG_PYTHON_THREAD_BEGIN_BLOCK; 
     126        /* Convert the arguments */ 
     127        PyInfo  = SWIG_NewPointerObj((void *)info,     SWIGTYPE_p_peer_info,     0 ); 
     128         
     129        /* Call the function */ 
     130        result = PyEval_CallFunction(validate_cb2_py, "(O)", PyInfo); 
     131         
     132        /* The result is an integer */ 
     133        if ((result == NULL) || !SWIG_IsOK(SWIG_AsVal_int(result, &ret))) { 
     134                fd_log_debug("Error: The Python callback did not return an integer.\n"); 
     135                ret = EINVAL; 
     136                goto out; 
     137        } 
     138         
     139out:     
     140        Py_XDECREF(result); 
     141        SWIG_PYTHON_THREAD_END_BLOCK; 
     142        return ret; 
     143} 
     144 
     145/* C wrapper that calls validate_cb_py */ 
     146int call_the_python_validate_callback(struct peer_info * info, int * auth, int (**cb2)(struct peer_info *)) { 
     147        PyObject *PyInfo; 
     148        PyObject *result = NULL; 
     149        int ret = 0; 
     150         
     151        if (!validate_cb_py) { 
     152                fd_log_debug("Internal error: missing the callback!\n"); 
     153                return ENOTSUP; 
     154        } 
     155         
     156        SWIG_PYTHON_THREAD_BEGIN_BLOCK; 
     157        /* Convert the arguments */ 
     158        PyInfo  = SWIG_NewPointerObj((void *)info,     SWIGTYPE_p_peer_info,     0 ); 
     159         
     160        /* Call the function */ 
     161        result = PyEval_CallFunction(validate_cb_py, "(O)", PyInfo); 
     162         
     163        /* The result is supposedly -1, 1, or a cb2 */ 
     164        if (result == NULL) { 
     165                fd_log_debug("Error: The Python callback did not return a value.\n"); 
     166                ret = EINVAL; 
     167                goto out; 
     168        } 
     169         
     170        if (PyCallable_Check(result)) { 
     171                if (cb2) { 
     172                        if (validate_cb2_py && (validate_cb2_py != result)) { 
     173                                fd_log_debug("Only 1 register callback2 is supported currently\n"); 
     174                                ret = ENOTSUP; 
     175                                goto out; 
     176                        } 
     177                        validate_cb2_py = result; 
     178                        *cb2 = call_the_python_validate_callback2; 
     179                        *auth = 1; 
     180                        goto out_nodec; 
     181                } else { 
     182                        *auth = 1; 
     183                        goto out; /* ignore the callback since it won't be used */ 
     184                } 
     185        } else { /* In this case, the return value must be -1, 0, or 1 */ 
     186                if (!SWIG_IsOK(SWIG_AsVal_int(result, auth))) { 
     187                        fd_log_debug("Error: Cannot convert the return value to integer.\n"); 
     188                        ret = EINVAL; 
     189                        goto out; 
     190                } 
     191        } 
     192         
     193out:     
     194        Py_XDECREF(result); 
     195out_nodec:       
     196        SWIG_PYTHON_THREAD_END_BLOCK; 
     197        TRACE_DEBUG(FULL, "ret=%d, *auth=%d, cb2=%p, *cb2=%p", ret, *auth, cb2, cb2 ? *cb2 : NULL); 
     198        return ret; 
     199} 
     200 
     201%} 
     202 
     203%inline %{ 
     204static void peer_validate_register(PyObject * PyCb) { 
     205        int ret ; 
     206         
     207        if (!PyCb) { 
     208                DI_ERROR(EINVAL, NULL, "The callback must be provided"); 
     209                return; 
     210        } 
     211         
     212        if (validate_cb_py) { 
     213                if (PyCb != validate_cb_py) { 
     214                        DI_ERROR(ENOTSUP, PyExc_RuntimeError, "Only 1 register callback is supported currently"); 
     215                        return; 
     216                } 
     217        } else { 
     218                validate_cb_py = PyCb; 
     219                Py_XINCREF(PyCb); 
     220        } 
     221         
     222        ret = fd_peer_validate_register ( call_the_python_validate_callback ); 
     223        if (ret) { 
     224                DI_ERROR(ret, NULL, NULL); 
     225        } 
     226} 
     227%} 
  • extensions/dbg_interactive/queues.i

    r638 r640  
    7777         
    7878        /* Post an item */ 
    79         void post(PyObject * item) { 
    80                 int ret; 
    81                 PyObject * i = item; 
    82                  
    83                 Py_XINCREF(i); 
    84                 ret = fd_fifo_post($self, &i); 
     79        void post(PyObject * item, char * type = NULL) { 
     80                int ret; 
     81                if (type) { 
     82                        void * real_obj = NULL; 
     83                        swig_type_info * desttype = NULL; 
     84                        desttype = SWIG_TypeQuery(type); 
     85                        if (!desttype) { 
     86                                DI_ERROR(EINVAL, NULL, "Unable to resolve this type. Please check the form: 'struct blahbla *'"); 
     87                                return; 
     88                        } 
     89                        /* Now, get the "real" value under the shadow umbrella */ 
     90                        ret = SWIG_ConvertPtr(item, &real_obj, desttype, SWIG_POINTER_DISOWN ); 
     91                        if (!SWIG_IsOK(ret)) { 
     92                                DI_ERROR(EINVAL, SWIG_ErrorType(ret), "Unable to convert the item to given type"); 
     93                                return; 
     94                        } 
     95                        ret = fd_fifo_post($self, &real_obj); 
     96                } else { 
     97                        PyObject * i = item; 
     98                        Py_XINCREF(i); 
     99                        ret = fd_fifo_post($self, &i); 
     100                } 
    85101                if (ret != 0) { 
    86102                        DI_ERROR(ret, NULL, NULL); 
     
    89105         
    90106        /* Get (blocking) */ 
    91         PyObject * get() { 
     107        PyObject * get(char * type = NULL) { 
    92108                int ret; 
    93109                PyObject * i = NULL; 
    94                  
    95                 ret = fd_fifo_get($self, &i); 
    96                 if (ret != 0) { 
    97                         DI_ERROR(ret, NULL, NULL); 
    98                 } 
    99                  
    100                 return i; 
     110                void * obj = NULL; 
     111                swig_type_info * desttype = NULL; 
     112                if (type) { 
     113                        desttype = SWIG_TypeQuery(type); 
     114                        if (!desttype) { 
     115                                DI_ERROR(EINVAL, NULL, "Unable to resolve this type. Please check the form: 'struct blahbla *'"); 
     116                                return NULL; 
     117                        } 
     118                } 
     119                 
     120                ret = fd_fifo_get($self, &obj); 
     121                if (ret != 0) { 
     122                        DI_ERROR(ret, NULL, NULL); 
     123                } 
     124                 
     125                if (type) { 
     126                        return SWIG_NewPointerObj(obj, desttype, 0 ); 
     127                } else { 
     128                        i = obj; 
     129                        return i; 
     130                } 
    101131        } 
    102132         
    103133        /* TryGet (non-blocking, returns None on empty queue) */ 
    104         PyObject * tryget() { 
     134        PyObject * tryget(char * type = NULL) { 
    105135                int ret; 
    106136                PyObject * i = NULL; 
    107                  
    108                 ret = fd_fifo_tryget($self, &i); 
     137                void * obj = NULL; 
     138                swig_type_info * desttype = NULL; 
     139                if (type) { 
     140                        desttype = SWIG_TypeQuery(type); 
     141                        if (!desttype) { 
     142                                DI_ERROR(EINVAL, NULL, "Unable to resolve this type. Please check the form: 'struct blahbla *'"); 
     143                                return NULL; 
     144                        } 
     145                } 
     146                 
     147                ret = fd_fifo_tryget($self, &obj); 
    109148                if (ret == EWOULDBLOCK) { 
    110149                        Py_XINCREF(Py_None); 
     
    115154                } 
    116155                 
    117                 return i; 
     156                if (type) { 
     157                        return SWIG_NewPointerObj(obj, desttype, 0 ); 
     158                } else { 
     159                        i = obj; 
     160                        return i; 
     161                } 
    118162        } 
    119163         
    120164        /* TimedGet (blocking for a while) */ 
    121         PyObject * timedget(long seconds) { 
     165        PyObject * timedget(long seconds, char * type = NULL) { 
    122166                int ret; 
    123167                PyObject * i = NULL; 
    124168                struct timespec ts; 
     169                void * obj = NULL; 
     170                swig_type_info * desttype = NULL; 
     171                if (type) { 
     172                        desttype = SWIG_TypeQuery(type); 
     173                        if (!desttype) { 
     174                                DI_ERROR(EINVAL, NULL, "Unable to resolve this type. Please check the form: 'struct blahbla *'"); 
     175                                return NULL; 
     176                        } 
     177                } 
    125178                 
    126179                clock_gettime(CLOCK_REALTIME, &ts); 
    127180                ts.tv_sec += seconds; 
    128181                 
    129                 ret = fd_fifo_timedget($self, &i, &ts); 
     182                ret = fd_fifo_timedget($self, &obj, &ts); 
    130183                if (ret == ETIMEDOUT) { 
    131184                        Py_XINCREF(Py_None); 
     
    136189                } 
    137190                 
    138                 return i; 
     191                if (type) { 
     192                        return SWIG_NewPointerObj(obj, desttype, 0 ); 
     193                } else { 
     194                        i = obj; 
     195                        return i; 
     196                } 
    139197        } 
    140198         
  • extensions/dbg_interactive/routing.i

    r637 r640  
    7777} 
    7878 
     79 
     80 
    7981%extend rtd_candidate { 
    8082        void dump() { 
     
    8688} 
    8789 
     90 
     91%{ 
     92/* call it (will be called from a different thread than the interpreter, when message arrives) */ 
     93static int call_the_python_rt_fwd_callback(void * pycb, struct msg **msg) { 
     94        PyObject *PyMsg; 
     95        PyObject *cb, *result = NULL; 
     96        int ret = 0; 
     97         
     98        if (!pycb) { 
     99                fd_log_debug("Internal error: missing the callback!\n"); 
     100                return ENOTSUP; 
     101        } 
     102        cb = pycb; 
     103         
     104        SWIG_PYTHON_THREAD_BEGIN_BLOCK; 
     105        /* Convert the arguments */ 
     106        PyMsg  = SWIG_NewPointerObj((void *)*msg,     SWIGTYPE_p_msg,     0 ); 
     107         
     108        /* Call the function */ 
     109        result = PyEval_CallFunction(cb, "(O)", PyMsg); 
     110         
     111        /* The result is supposedly composed of: [ ret, *msg ] */ 
     112        if ((result == NULL) || (!PyList_Check(result)) || (PyList_Size(result) != 2)) { 
     113                fd_log_debug("Error: The Python callback did not return [ ret, msg ].\n"); 
     114                ret = EINVAL; 
     115                goto out; 
     116        } 
     117         
     118        /* Convert the return values */ 
     119        if (!SWIG_IsOK(SWIG_AsVal_int(PyList_GetItem(result, 0), &ret))) { 
     120                fd_log_debug("Error: Cannot convert the first return value to integer.\n"); 
     121                ret = EINVAL; 
     122                goto out; 
     123        } 
     124        if (ret) { 
     125                TRACE_DEBUG(INFO, "The Python callback returned the error code %d (%s)\n", ret, strerror(ret)); 
     126                goto out; 
     127        } 
     128         
     129        if (!SWIG_IsOK(SWIG_ConvertPtr(PyList_GetItem(result, 1), (void *)msg, SWIGTYPE_p_msg, SWIG_POINTER_DISOWN))) { 
     130                fd_log_debug("Error: Cannot convert the second return value to message.\n"); 
     131                ret = EINVAL; 
     132                goto out; 
     133        } 
     134         
     135out:     
     136        Py_XDECREF(result); 
     137         
     138        SWIG_PYTHON_THREAD_END_BLOCK; 
     139        return ret; 
     140} 
     141%} 
     142 
     143 
     144struct fd_rt_fwd_hdl { 
     145}; 
     146 
     147%extend fd_rt_fwd_hdl{ 
     148        fd_rt_fwd_hdl(PyObject * PyCb, enum fd_rt_fwd_dir dir) { 
     149                struct fd_rt_fwd_hdl * r = NULL; 
     150                int ret; 
     151                 
     152                Py_XINCREF(PyCb); 
     153 
     154                ret = fd_rt_fwd_register( call_the_python_rt_fwd_callback, PyCb, dir, &r ); 
     155                if (ret != 0) { 
     156                        DI_ERROR(ret, NULL, NULL); 
     157                        return NULL; 
     158                } 
     159                return r; 
     160        } 
     161         
     162        ~fd_rt_fwd_hdl() { 
     163                PyObject * func; 
     164                int ret = fd_rt_fwd_unregister ( $self, (void *) &func ); 
     165                if (ret != 0) { 
     166                        DI_ERROR(ret, NULL, NULL); 
     167                        return; 
     168                } 
     169                Py_XDECREF(func); 
     170                return; 
     171        } 
     172} 
     173 
     174 
     175%{ 
     176/* call it (will be called from a different thread than the interpreter, when message arrives) */ 
     177static int call_the_python_rt_out_callback(void * pycb, struct msg *msg, struct fd_list * candidates) { 
     178        PyObject *PyMsg, *PyCands; 
     179        PyObject *cb, *result = NULL; 
     180        int ret = 0; 
     181         
     182        if (!pycb) { 
     183                fd_log_debug("Internal error: missing the callback!\n"); 
     184                return ENOTSUP; 
     185        } 
     186        cb = pycb; 
     187         
     188        SWIG_PYTHON_THREAD_BEGIN_BLOCK; 
     189        /* Convert the arguments */ 
     190        PyMsg   = SWIG_NewPointerObj((void *)msg,        SWIGTYPE_p_msg,     0 ); 
     191        PyCands = SWIG_NewPointerObj((void *)candidates, SWIGTYPE_p_fd_list, 0 ); 
     192         
     193        /* Call the function */ 
     194        result = PyEval_CallFunction(cb, "(OO)", PyMsg, PyCands); 
     195         
     196        /* The result is supposedly composed of: [ ret, *msg ] */ 
     197        if (result == NULL){ 
     198                fd_log_debug("Error: The Python callback raised an exception.\n"); 
     199                ret = EINVAL; 
     200                goto out; 
     201        } 
     202         
     203        /* Convert the return values */ 
     204        if (!SWIG_IsOK(SWIG_AsVal_int(result, &ret))) { 
     205                fd_log_debug("Error: Cannot convert the return value to integer.\n"); 
     206                ret = EINVAL; 
     207                goto out; 
     208        } 
     209out:     
     210        Py_XDECREF(result); 
     211         
     212        SWIG_PYTHON_THREAD_END_BLOCK; 
     213        return ret; 
     214} 
     215%} 
     216 
     217 
     218struct fd_rt_out_hdl { 
     219}; 
     220 
     221%extend fd_rt_out_hdl{ 
     222        fd_rt_out_hdl(PyObject * PyCb, int priority = 0) { 
     223                struct fd_rt_out_hdl * r = NULL; 
     224                int ret; 
     225                 
     226                Py_XINCREF(PyCb); 
     227 
     228                ret = fd_rt_out_register( call_the_python_rt_out_callback, PyCb, priority, &r ); 
     229                if (ret != 0) { 
     230                        DI_ERROR(ret, NULL, NULL); 
     231                        return NULL; 
     232                } 
     233                return r; 
     234        } 
     235         
     236        ~fd_rt_out_hdl() { 
     237                PyObject * func; 
     238                int ret = fd_rt_out_unregister ( $self, (void *) &func ); 
     239                if (ret != 0) { 
     240                        DI_ERROR(ret, NULL, NULL); 
     241                        return; 
     242                } 
     243                Py_XDECREF(func); 
     244                return; 
     245        } 
     246} 
     247 
  • freeDiameter/endpoints.c

    r559 r640  
    5353        CHECK_PARAMS( list && sa && (sl <= sizeof(sSS)) ); 
    5454         
     55        if (list->next == NULL) { 
     56                /* the list is not initialized yet, do it */ 
     57                fd_list_init(list, NULL); 
     58        } 
     59         
    5560        if (TRACE_BOOL(ANNOYING + 1)) { 
    5661                TRACE_DEBUG(ANNOYING, "  DEBUG:fd_ep_add_merge  Current list:"); 
  • include/freeDiameter/freeDiameter.h

    r628 r640  
    7070 
    7171/* Structure to hold the configuration of the freeDiameter daemon */ 
     72#define EYEC_CONFIG     0xC011F16 
    7273struct fd_config { 
    7374        int              cnf_eyec;      /* Eye catcher: EYEC_CONFIG */ 
    74                         #define EYEC_CONFIG     0xC011F16 
    7575         
    7676        char            *cnf_file;      /* Configuration file to parse, default is DEFAULT_CONF_FILE */ 
     
    178178        (((unsigned)(state)) <= STATE_MAX ? peer_state_str[((unsigned)(state)) ] : "<Invalid>") 
    179179 
     180/* Constants for the peer_info structure bellow */ 
     181#define PI_P3_DEFAULT   0       /* Use any available protocol */ 
     182#define PI_P3_IP        1       /* Use only IP to connect to this peer */ 
     183#define PI_P3_IPv6      2       /* resp, IPv6 */ 
     184 
     185#define PI_P4_DEFAULT   0       /* Attempt any available protocol */ 
     186#define PI_P4_TCP       1       /* Only use TCP */ 
     187#define PI_P4_SCTP      2       /* Only use SCTP */ 
     188 
     189#define PI_ALGPREF_SCTP 0       /* SCTP is  attempted first (default) */ 
     190#define PI_ALGPREF_TCP  1       /* TCP is attempted first */ 
     191 
     192#define PI_SEC_DEFAULT  0       /* New TLS security (handshake after connection, protecting also CER/CEA) */ 
     193#define PI_SEC_NONE     1       /* Transparent security with this peer (IPsec) */ 
     194#define PI_SEC_TLS_OLD  2       /* Old TLS security (use Inband-Security-Id AVP during CER/CEA) */ 
     195                                /* Set sec = 3 to authorize use of (Inband-Security-Id == NONE) with this peer, sec = 2 only authorizing TLS */ 
     196 
     197#define PI_EXP_NONE     0       /* the peer entry does not expire */ 
     198#define PI_EXP_INACTIVE 1       /* the peer entry expires (i.e. is deleted) after pi_lft seconds without activity */ 
     199 
     200#define PI_PRST_NONE    0       /* the peer entry is deleted after disconnection / error */ 
     201#define PI_PRST_ALWAYS  1       /* the peer entry is persistant (will be kept as ZOMBIE in case of error) */ 
     202                         
    180203/* Information about a remote peer */ 
    181204struct peer_info { 
     
    185208        struct { 
    186209                struct { 
    187                         #define PI_P3_DEFAULT   0       /* Use any available protocol */ 
    188                         #define PI_P3_IP        1       /* Use only IP to connect to this peer */ 
    189                         #define PI_P3_IPv6      2       /* resp, IPv6 */ 
    190                         unsigned        pro3 :2; 
    191  
    192                         #define PI_P4_DEFAULT   0       /* Attempt any available protocol */ 
    193                         #define PI_P4_TCP       1       /* Only use TCP */ 
    194                         #define PI_P4_SCTP      2       /* Only use SCTP */ 
    195                         unsigned        pro4 :2; 
    196  
    197                         #define PI_ALGPREF_SCTP 0       /* SCTP is  attempted first (default) */ 
    198                         #define PI_ALGPREF_TCP  1       /* TCP is attempted first */ 
    199                         unsigned        alg :1; 
    200  
    201                         #define PI_SEC_DEFAULT  0       /* New TLS security (handshake after connection, protecting also CER/CEA) */ 
    202                         #define PI_SEC_NONE     1       /* Transparent security with this peer (IPsec) */ 
    203                         #define PI_SEC_TLS_OLD  2       /* Old TLS security (use Inband-Security-Id AVP during CER/CEA) */ 
    204                         unsigned        sec :2;         /* Set sec = 3 to authorize use of (Inband-Security-Id == NONE) with this peer, sec = 2 only authorizing TLS */ 
    205  
    206                         #define PI_EXP_NONE     0       /* the peer entry does not expire */ 
    207                         #define PI_EXP_INACTIVE 1       /* the peer entry expires (i.e. is deleted) after pi_lft seconds without activity */ 
    208                         unsigned        exp :1; 
    209  
    210                         #define PI_PRST_NONE    0       /* the peer entry is deleted after disconnection / error */ 
    211                         #define PI_PRST_ALWAYS  1       /* the peer entry is persistant (will be kept as ZOMBIE in case of error) */ 
    212                         unsigned        persist :1; 
     210                        unsigned        pro3 :2;        /* PI_P3_* */ 
     211                        unsigned        pro4 :2;        /* PI_P4_* */ 
     212                        unsigned        alg :1;         /* PI_ALGPREF_* */ 
     213                        unsigned        sec :2;         /* PI_SEC_* */ 
     214                        unsigned        exp :1;         /* PI_EXP_* */ 
     215                        unsigned        persist :1;     /* PI_PRST_* */ 
    213216                         
    214217                }               pic_flags;      /* Flags influencing the connection to the remote peer */ 
Note: See TracChangeset for help on using the changeset viewer.