Navigation


source: freeDiameter/extensions/dbg_interactive/peers.i @ 706:4ffbc9f1e922

Last change on this file since 706:4ffbc9f1e922 was 706:4ffbc9f1e922, checked in by Sebastien Decugis <sdecugis@nict.go.jp>, 11 years ago

Large UNTESTED commit with the following changes:

  • Improved DiameterIdentity? handling (esp. interationalization issues), and improve efficiency of some string operations in peers, sessions, and dictionary modules (closes #7)
  • Cleanup in the session module to free only unreferenced sessions (#16)
  • Removed fd_cpu_flush_cache(), replaced by more robust alternatives.
  • Improved peer state machine algorithm to counter SCTP multistream race condition.
File size: 6.6 KB
Line 
1/*********************************************************************************************************
2* Software License Agreement (BSD License)                                                               *
3* Author: Sebastien Decugis <sdecugis@nict.go.jp>                                                        *
4*                                                                                                        *
5* Copyright (c) 2010, WIDE Project and NICT                                                              *
6* All rights reserved.                                                                                   *
7*                                                                                                        *
8* Redistribution and use of this software in source and binary forms, with or without modification, are  *
9* permitted provided that the following conditions are met:                                              *
10*                                                                                                        *
11* * Redistributions of source code must retain the above                                                 *
12*   copyright notice, this list of conditions and the                                                    *
13*   following disclaimer.                                                                                *
14*                                                                                                        *
15* * Redistributions in binary form must reproduce the above                                              *
16*   copyright notice, this list of conditions and the                                                    *
17*   following disclaimer in the documentation and/or other                                               *
18*   materials provided with the distribution.                                                            *
19*                                                                                                        *
20* * Neither the name of the WIDE Project or NICT nor the                                                 *
21*   names of its contributors may be used to endorse or                                                  *
22*   promote products derived from this software without                                                  *
23*   specific prior written permission of WIDE Project and                                                *
24*   NICT.                                                                                                *
25*                                                                                                        *
26* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
27* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
28* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
29* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT     *
30* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS    *
31* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
32* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
33* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                                             *
34*********************************************************************************************************/
35
36/* Do not include this directly, use dbg_interactive.i instead */
37
38/****** PEERS *********/
39
40%{
41static void fd_add_cb(struct peer_info *peer, void *data) {
42        /* Callback called when the peer connection completes (or fails) */
43        PyObject *PyPeer, *PyFunc;
44        PyObject *result = NULL;
45       
46        if (!data) {
47                TRACE_DEBUG(INFO, "Internal error: missing callback\n");
48                return;
49        }
50        PyFunc = data;
51       
52        SWIG_PYTHON_THREAD_BEGIN_BLOCK;
53       
54        /* Convert the argument */
55        PyPeer  = SWIG_NewPointerObj((void *)peer,     SWIGTYPE_p_peer_info,     0 );
56       
57        /* Call the function */
58        result = PyEval_CallFunction(PyFunc, "(O)", PyPeer);
59       
60        Py_XDECREF(result);
61        Py_XDECREF(PyFunc);
62       
63        SWIG_PYTHON_THREAD_END_BLOCK;
64        return;
65}
66%}
67
68%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
81        /* Wrapper around fd_peer_add to allow calling the python callback */
82        %delobject add;
83        void add(PyObject * PyCb=NULL) {
84                int ret;
85               
86                if (PyCb) {
87                        Py_XINCREF(PyCb);
88                        ret = fd_peer_add ( $self, "dbg_interactive", fd_add_cb, PyCb );
89                } else {
90                        ret = fd_peer_add ( $self, "dbg_interactive", NULL, NULL );
91                }
92                if (ret != 0) {
93                        DI_ERROR(ret, NULL, NULL);
94                }
95        }
96}
97
98%inline %{
99static struct peer_hdr * peer_search(char *STRING, size_t LENGTH) {
100        struct peer_hdr *r = NULL;
101        int ret = fd_peer_getbyid( STRING, LENGTH, 0, &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%}
Note: See TracBrowser for help on using the repository browser.