Navigation


Changeset 640:237cf6339546 in freeDiameter


Ignore:
Timestamp:
Dec 20, 2010, 7:36:40 PM (13 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
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.