Index: extensions/dbg_interactive/routing.i
===================================================================
--- extensions/dbg_interactive/routing.i	(revision 637)
+++ extensions/dbg_interactive/routing.i	(revision 640)
@@ -77,4 +77,6 @@
 }
 
+
+
 %extend rtd_candidate {
 	void dump() {
@@ -86,2 +88,160 @@
 }
 
+
+%{
+/* call it (will be called from a different thread than the interpreter, when message arrives) */
+static int call_the_python_rt_fwd_callback(void * pycb, struct msg **msg) {
+	PyObject *PyMsg;
+	PyObject *cb, *result = NULL;
+	int ret = 0;
+	
+	if (!pycb) {
+		fd_log_debug("Internal error: missing the callback!\n");
+		return ENOTSUP;
+	}
+	cb = pycb;
+	
+	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+	/* Convert the arguments */
+	PyMsg  = SWIG_NewPointerObj((void *)*msg,     SWIGTYPE_p_msg,     0 );
+	
+	/* Call the function */
+	result = PyEval_CallFunction(cb, "(O)", PyMsg);
+	
+	/* The result is supposedly composed of: [ ret, *msg ] */
+	if ((result == NULL) || (!PyList_Check(result)) || (PyList_Size(result) != 2)) {
+		fd_log_debug("Error: The Python callback did not return [ ret, msg ].\n");
+		ret = EINVAL;
+		goto out;
+	}
+	
+	/* Convert the return values */
+	if (!SWIG_IsOK(SWIG_AsVal_int(PyList_GetItem(result, 0), &ret))) {
+		fd_log_debug("Error: Cannot convert the first return value to integer.\n");
+		ret = EINVAL;
+		goto out;
+	}
+	if (ret) {
+		TRACE_DEBUG(INFO, "The Python callback returned the error code %d (%s)\n", ret, strerror(ret));
+		goto out;
+	}
+	
+	if (!SWIG_IsOK(SWIG_ConvertPtr(PyList_GetItem(result, 1), (void *)msg, SWIGTYPE_p_msg, SWIG_POINTER_DISOWN))) {
+		fd_log_debug("Error: Cannot convert the second return value to message.\n");
+		ret = EINVAL;
+		goto out;
+	}
+	
+out:	
+	Py_XDECREF(result);
+	
+	SWIG_PYTHON_THREAD_END_BLOCK;
+	return ret;
+}
+%}
+
+
+struct fd_rt_fwd_hdl {
+};
+
+%extend fd_rt_fwd_hdl{
+	fd_rt_fwd_hdl(PyObject * PyCb, enum fd_rt_fwd_dir dir) {
+		struct fd_rt_fwd_hdl * r = NULL;
+		int ret;
+		
+		Py_XINCREF(PyCb);
+
+		ret = fd_rt_fwd_register( call_the_python_rt_fwd_callback, PyCb, dir, &r );
+		if (ret != 0) {
+			DI_ERROR(ret, NULL, NULL);
+			return NULL;
+		}
+		return r;
+	}
+	
+	~fd_rt_fwd_hdl() {
+		PyObject * func;
+		int ret = fd_rt_fwd_unregister ( $self, (void *) &func );
+		if (ret != 0) {
+			DI_ERROR(ret, NULL, NULL);
+			return;
+		}
+		Py_XDECREF(func);
+		return;
+	}
+}
+
+
+%{
+/* call it (will be called from a different thread than the interpreter, when message arrives) */
+static int call_the_python_rt_out_callback(void * pycb, struct msg *msg, struct fd_list * candidates) {
+	PyObject *PyMsg, *PyCands;
+	PyObject *cb, *result = NULL;
+	int ret = 0;
+	
+	if (!pycb) {
+		fd_log_debug("Internal error: missing the callback!\n");
+		return ENOTSUP;
+	}
+	cb = pycb;
+	
+	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+	/* Convert the arguments */
+	PyMsg   = SWIG_NewPointerObj((void *)msg,        SWIGTYPE_p_msg,     0 );
+	PyCands = SWIG_NewPointerObj((void *)candidates, SWIGTYPE_p_fd_list, 0 );
+	
+	/* Call the function */
+	result = PyEval_CallFunction(cb, "(OO)", PyMsg, PyCands);
+	
+	/* The result is supposedly composed of: [ ret, *msg ] */
+	if (result == NULL){
+		fd_log_debug("Error: The Python callback raised an exception.\n");
+		ret = EINVAL;
+		goto out;
+	}
+	
+	/* Convert the return values */
+	if (!SWIG_IsOK(SWIG_AsVal_int(result, &ret))) {
+		fd_log_debug("Error: Cannot convert the return value to integer.\n");
+		ret = EINVAL;
+		goto out;
+	}
+out:	
+	Py_XDECREF(result);
+	
+	SWIG_PYTHON_THREAD_END_BLOCK;
+	return ret;
+}
+%}
+
+
+struct fd_rt_out_hdl {
+};
+
+%extend fd_rt_out_hdl{
+	fd_rt_out_hdl(PyObject * PyCb, int priority = 0) {
+		struct fd_rt_out_hdl * r = NULL;
+		int ret;
+		
+		Py_XINCREF(PyCb);
+
+		ret = fd_rt_out_register( call_the_python_rt_out_callback, PyCb, priority, &r );
+		if (ret != 0) {
+			DI_ERROR(ret, NULL, NULL);
+			return NULL;
+		}
+		return r;
+	}
+	
+	~fd_rt_out_hdl() {
+		PyObject * func;
+		int ret = fd_rt_out_unregister ( $self, (void *) &func );
+		if (ret != 0) {
+			DI_ERROR(ret, NULL, NULL);
+			return;
+		}
+		Py_XDECREF(func);
+		return;
+	}
+}
+
