annotate freeDiameter/routing.c @ 89:3f8b437bcb66

Added some default routing handlers
author Sebastien Decugis <sdecugis@nict.go.jp>
date Mon, 07 Dec 2009 16:56:42 +0900
parents 9e2db1647d6f
children 2c9444152e4b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
1 /*********************************************************************************************************
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
2 * Software License Agreement (BSD License) *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
3 * Author: Sebastien Decugis <sdecugis@nict.go.jp> *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
4 * *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
5 * Copyright (c) 2009, WIDE Project and NICT *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
6 * All rights reserved. *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
7 * *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
8 * Redistribution and use of this software in source and binary forms, with or without modification, are *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
9 * permitted provided that the following conditions are met: *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
10 * *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
11 * * Redistributions of source code must retain the above *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
12 * copyright notice, this list of conditions and the *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
13 * following disclaimer. *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
14 * *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
15 * * Redistributions in binary form must reproduce the above *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
16 * copyright notice, this list of conditions and the *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
17 * following disclaimer in the documentation and/or other *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
18 * materials provided with the distribution. *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
19 * *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
20 * * Neither the name of the WIDE Project or NICT nor the *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
21 * names of its contributors may be used to endorse or *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
22 * promote products derived from this software without *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
23 * specific prior written permission of WIDE Project and *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
24 * NICT. *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
25 * *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
27 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
28 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
29 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
32 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
33 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
34 *********************************************************************************************************/
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
35
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
36 #include "fD.h"
c5c99c73c2bf Added some extensions and functions in the daemon
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
diff changeset
37
86
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
38 /********************************************************************************/
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
39 /* First part : handling the extensions callbacks */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
40 /********************************************************************************/
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
41
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
42 /* Lists of the callbacks, and locks to protect them */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
43 static pthread_rwlock_t rt_fwd_lock = PTHREAD_RWLOCK_INITIALIZER;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
44 static struct fd_list rt_fwd_list = FD_LIST_INITIALIZER_O(rt_fwd_list, &rt_fwd_lock);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
45
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
46 static pthread_rwlock_t rt_out_lock = PTHREAD_RWLOCK_INITIALIZER;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
47 static struct fd_list rt_out_list = FD_LIST_INITIALIZER_O(rt_out_list, &rt_out_lock);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
48
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
49 /* Items in the lists are the same */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
50 struct rt_hdl {
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
51 struct fd_list chain; /* link in the rt_fwd_list or rt_out_list */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
52 void * cbdata; /* the registered data */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
53 union {
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
54 int order; /* This value is used to sort the list */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
55 int dir; /* It is the direction for FWD handlers */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
56 int prio; /* and the priority for OUT handlers */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
57 };
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
58 union {
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
59 int (*rt_fwd_cb)(void * cbdata, struct msg ** msg);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
60 int (*rt_out_cb)(void * cbdata, struct msg * msg, struct fd_list * candidates);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
61 };
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
62 };
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
63
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
64 /* Add a new entry in the list */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
65 static int add_ordered(struct rt_hdl * new, struct fd_list * list)
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
66 {
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
67 /* The list is ordered by prio parameter */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
68 struct fd_list * li;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
69
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
70 CHECK_POSIX( pthread_rwlock_wrlock(list->o) );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
71
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
72 for (li = list->next; li != list; li = li->next) {
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
73 struct rt_hdl * h = (struct rt_hdl *) li;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
74 if (new->order <= h->order)
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
75 break;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
76 }
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
77
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
78 fd_list_insert_before(li, &new->chain);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
79
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
80 CHECK_POSIX( pthread_rwlock_unlock(list->o) );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
81 }
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
82
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
83 /* Register a new FWD callback */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
84 int fd_rt_fwd_register ( int (*rt_fwd_cb)(void * cbdata, struct msg ** msg), void * cbdata, enum fd_rt_fwd_dir dir, struct fd_rt_fwd_hdl ** handler )
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
85 {
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
86 struct rt_hdl * new;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
87
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
88 TRACE_ENTRY("%p %p %d %p", rt_fwd_cb, cbdata, dir, handler);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
89 CHECK_PARAMS( rt_fwd_cb );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
90 CHECK_PARAMS( (dir >= RT_FWD_REQ) && ( dir <= RT_FWD_ANS) );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
91
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
92 /* Create a new container */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
93 CHECK_MALLOC(new = malloc(sizeof(struct rt_hdl)));
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
94 memset(new, 0, sizeof(struct rt_hdl));
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
95
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
96 /* Write the content */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
97 fd_list_init(&new->chain, NULL);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
98 new->cbdata = cbdata;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
99 new->dir = dir;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
100 new->rt_fwd_cb = rt_fwd_cb;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
101
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
102 /* Save this in the list */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
103 CHECK_FCT( add_ordered(new, &rt_fwd_list) );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
104
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
105 /* Give it back to the extension if needed */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
106 if (handler)
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
107 *handler = (void *)new;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
108
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
109 return 0;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
110 }
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
111
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
112 /* Remove it */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
113 int fd_rt_fwd_unregister ( struct fd_rt_fwd_hdl * handler, void ** cbdata )
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
114 {
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
115 struct rt_hdl * del;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
116 TRACE_ENTRY( "%p %p", handler, cbdata);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
117 CHECK_PARAMS( handler );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
118
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
119 del = (struct rt_hdl *)handler;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
120 CHECK_PARAMS( del->chain.head == &rt_fwd_list );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
121
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
122 /* Unlink */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
123 CHECK_POSIX( pthread_rwlock_wrlock(&rt_fwd_lock) );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
124 fd_list_unlink(&del->chain);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
125 CHECK_POSIX( pthread_rwlock_unlock(&rt_fwd_lock) );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
126
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
127 if (cbdata)
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
128 *cbdata = del->cbdata;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
129
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
130 free(del);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
131 return 0;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
132 }
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
133
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
134 /* Register a new OUT callback */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
135 int fd_rt_out_register ( int (*rt_out_cb)(void * cbdata, struct msg * msg, struct fd_list * candidates), void * cbdata, int priority, struct fd_rt_out_hdl ** handler )
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
136 {
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
137 struct rt_hdl * new;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
138
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
139 TRACE_ENTRY("%p %p %d %p", rt_out_cb, cbdata, priority, handler);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
140 CHECK_PARAMS( rt_out_cb );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
141
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
142 /* Create a new container */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
143 CHECK_MALLOC(new = malloc(sizeof(struct rt_hdl)));
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
144 memset(new, 0, sizeof(struct rt_hdl));
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
145
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
146 /* Write the content */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
147 fd_list_init(&new->chain, NULL);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
148 new->cbdata = cbdata;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
149 new->prio = priority;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
150 new->rt_out_cb = rt_out_cb;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
151
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
152 /* Save this in the list */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
153 CHECK_FCT( add_ordered(new, &rt_out_list) );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
154
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
155 /* Give it back to the extension if needed */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
156 if (handler)
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
157 *handler = (void *)new;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
158
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
159 return 0;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
160 }
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
161
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
162 /* Remove it */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
163 int fd_rt_out_unregister ( struct fd_rt_out_hdl * handler, void ** cbdata )
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
164 {
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
165 struct rt_hdl * del;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
166 TRACE_ENTRY( "%p %p", handler, cbdata);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
167 CHECK_PARAMS( handler );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
168
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
169 del = (struct rt_hdl *)handler;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
170 CHECK_PARAMS( del->chain.head == &rt_out_list );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
171
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
172 /* Unlink */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
173 CHECK_POSIX( pthread_rwlock_wrlock(&rt_out_lock) );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
174 fd_list_unlink(&del->chain);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
175 CHECK_POSIX( pthread_rwlock_unlock(&rt_out_lock) );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
176
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
177 if (cbdata)
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
178 *cbdata = del->cbdata;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
179
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
180 free(del);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
181 return 0;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
182 }
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
183
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
184 /********************************************************************************/
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
185 /* Second part : the routing threads */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
186 /********************************************************************************/
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
187
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
188 /* Note: in the first version, we only create one thread of each kind.
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
189 We could improve the scalability by using the threshold feature of the queues fd_g_incoming and fd_g_outgoing
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
190 ( fd_g_local is managed by the dispatch thread ) to create additional threads if a queue is filling up.
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
191 */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
192
87
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
193 /* Test if a User-Name AVP contains a Decorated NAI -- RFC4282, draft-ietf-dime-nai-routing-04 */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
194 static int is_decorated_NAI(union avp_value * un)
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
195 {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
196 int i;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
197 TRACE_ENTRY("%p", un);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
198
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
199 /* If there was no User-Name, we return false */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
200 if (un == NULL)
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
201 return 0;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
202
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
203 /* Search if there is a '!' before any '@' -- do we need to check it contains a '.' ? */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
204 for (i = 0; i < un->os.len; i++) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
205 if ( un->os.data[i] == (unsigned char) '!' )
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
206 return 1;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
207 if ( un->os.data[i] == (unsigned char) '@' )
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
208 break;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
209 if ( un->os.data[i] == (unsigned char) '\\' )
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
210 i++; /* next one was escaped */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
211 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
212
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
213 return 0;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
214 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
215
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
216 /* Create new User-Name and Destination-Realm values */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
217 static int process_decorated_NAI(union avp_value * un, union avp_value * dr)
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
218 {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
219 int i, at_idx = 0, sep_idx = 0;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
220 unsigned char * old_un;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
221 TRACE_ENTRY("%p %p", un, dr);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
222 CHECK_PARAMS(un && dr);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
223
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
224 /* Save the decorated User-Name, for example 'homerealm.example.net!user@otherrealm.example.net' */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
225 old_un = un->os.data;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
226
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
227 /* Search the positions of the first '!' and the '@' in the string */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
228 for (i = 0; i < un->os.len; i++) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
229 if ( (!sep_idx) && (old_un[i] == (unsigned char) '!') )
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
230 sep_idx = i;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
231 if ( old_un[i] == (unsigned char) '@' ) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
232 at_idx = i;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
233 break;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
234 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
235 if ( un->os.data[i] == (unsigned char) '\\' )
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
236 i++; /* next one is escaped */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
237 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
238
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
239 CHECK_PARAMS( 0 < sep_idx < at_idx < un->os.len);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
240
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
241 /* Create the new User-Name value */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
242 CHECK_MALLOC( un->os.data = malloc( at_idx ) );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
243 memcpy( un->os.data, old_un + sep_idx + 1, at_idx - sep_idx ); /* user@ */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
244 memcpy( un->os.data + at_idx - sep_idx, old_un, sep_idx ); /* homerealm.example.net */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
245
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
246 /* Create the new Destination-Realm value */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
247 CHECK_MALLOC( dr->os.data = realloc(dr->os.data, sep_idx) );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
248 memcpy( dr->os.data, old_un, sep_idx );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
249 dr->os.len = sep_idx;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
250
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
251 TRACE_DEBUG(FULL, "Processed Decorated NAI '%.*s' into '%.*s' (%.*s)",
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
252 un->os.len, old_un,
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
253 at_idx, un->os.data,
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
254 dr->os.len, dr->os.data);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
255
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
256 un->os.len = at_idx;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
257 free(old_un);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
258
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
259 return 0;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
260 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
261
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
262
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
263
86
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
264 /* Function to return an error to an incoming request */
87
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
265 static int return_error(struct msg * msg, char * error_code, char * error_message, struct avp * failedavp)
86
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
266 {
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
267 struct fd_peer * peer;
88
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
268 int is_loc = 0;
86
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
269
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
270 /* Get the source of the message */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
271 {
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
272 char * id;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
273 CHECK_FCT( fd_msg_source_get( msg, &id ) );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
274
88
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
275 if (id == NULL) {
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
276 is_loc = 1; /* The message was issued locally */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
277 } else {
86
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
278
88
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
279 /* Search the peer with this id */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
280 CHECK_FCT( fd_peer_getbyid( id, (void *)&peer ) );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
281
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
282 if (!peer) {
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
283 TRACE_DEBUG(INFO, "Unable to send error '%s' to deleted peer '%s' in reply to:", error_code, id);
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
284 fd_msg_dump_walk(INFO, msg);
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
285 fd_msg_free(msg);
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
286 return 0;
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
287 }
86
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
288 }
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
289 }
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
290
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
291 /* Create the error message */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
292 CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, &msg, MSGFL_ANSW_ERROR ) );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
293
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
294 /* Set the error code */
87
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
295 CHECK_FCT( fd_msg_rescode_set(msg, error_code, error_message, failedavp, 1 ) );
86
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
296
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
297 /* Send the answer */
88
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
298 if (is_loc) {
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
299 CHECK_FCT( fd_fifo_post(fd_g_incoming, &msg) );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
300 } else {
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
301 CHECK_FCT( fd_out_send(&msg, NULL, peer) );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
302 }
86
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
303
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
304 /* Done */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
305 return 0;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
306 }
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
307
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
308 /* The (routing-in) thread -- see description in freeDiameter.h */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
309 static void * routing_in_thr(void * arg)
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
310 {
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
311 TRACE_ENTRY("%p", arg);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
312
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
313 /* Set the thread name */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
314 if (arg) {
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
315 char buf[48];
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
316 snprintf(buf, sizeof(buf), "Routing-IN %p", arg);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
317 fd_log_threadname ( buf );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
318 } else {
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
319 fd_log_threadname ( "Routing-IN" );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
320 }
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
321
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
322 /* Main thread loop */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
323 do {
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
324 struct msg * msg;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
325 struct msg_hdr * hdr;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
326 int is_req = 0;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
327 int is_err = 0;
87
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
328 char * qry_src = NULL;
86
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
329
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
330 /* Test if we were told to stop */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
331 pthread_testcancel();
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
332
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
333 /* Get the next message from the incoming queue */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
334 CHECK_FCT_DO( fd_fifo_get ( fd_g_incoming, &msg ), goto fatal_error );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
335
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
336 if (TRACE_BOOL(FULL)) {
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
337 TRACE_DEBUG(FULL, "Picked next message:");
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
338 fd_msg_dump_one(FULL, msg);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
339 }
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
340
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
341 /* Read the message header */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
342 CHECK_FCT_DO( fd_msg_hdr(msg, &hdr), goto fatal_error );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
343 is_req = hdr->msg_flags & CMD_FLAG_REQUEST;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
344 is_err = hdr->msg_flags & CMD_FLAG_ERROR;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
345
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
346 /* Handle incorrect bits */
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
347 if (is_req && is_err) {
87
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
348 CHECK_FCT_DO( return_error( msg, "DIAMETER_INVALID_HDR_BITS", "R & E bits were set", NULL), goto fatal_error );
86
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
349 continue;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
350 }
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
351
87
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
352 /* If it is a request, we must analyze its content to decide what we do with it */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
353 if (is_req) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
354 struct avp * avp, *un = NULL;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
355 union avp_value * un_val = NULL, *dr_val = NULL;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
356 enum status { UNKNOWN, YES, NO };
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
357 /* Are we Destination-Host? */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
358 enum status is_dest_host = UNKNOWN;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
359 /* Are we Destination-Realm? */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
360 enum status is_dest_realm = UNKNOWN;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
361 /* Do we support the application of the message? */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
362 enum status is_local_app = UNKNOWN;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
363
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
364 /* Check if we have local support for the message application */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
365 if ( (hdr->msg_appl == 0) || (hdr->msg_appl == AI_RELAY) ) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
366 TRACE_DEBUG(INFO, "Received a routable message with application id 0, returning DIAMETER_APPLICATION_UNSUPPORTED");
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
367 CHECK_FCT_DO( return_error( msg, "DIAMETER_APPLICATION_UNSUPPORTED", "Routable message with application id 0 or relay", NULL), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
368 continue;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
369 } else {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
370 struct fd_app * app;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
371 CHECK_FCT_DO( fd_app_check(&fd_g_config->cnf_apps, hdr->msg_appl, &app), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
372 is_local_app = (app ? YES : NO);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
373 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
374
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
375 /* Parse the message for Dest-Host and Dest-Realm */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
376 CHECK_FCT_DO( fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, &avp, NULL), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
377 while (avp) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
378 struct avp_hdr * ahdr;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
379 CHECK_FCT_DO( fd_msg_avp_hdr( avp, &ahdr ), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
380
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
381 if (! (ahdr->avp_flags & AVP_FLAG_VENDOR)) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
382 switch (ahdr->avp_code) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
383 case AC_DESTINATION_HOST:
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
384 /* Parse this AVP */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
385 CHECK_FCT_DO( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
386 ASSERT( ahdr->avp_value );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
387 /* Compare the Destination-Host AVP of the message with our identity */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
388 if (ahdr->avp_value->os.len != fd_g_config->cnf_diamid_len) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
389 is_dest_host = NO;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
390 } else {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
391 is_dest_host = (strncasecmp(fd_g_config->cnf_diamid, (char *)ahdr->avp_value->os.data, fd_g_config->cnf_diamid_len)
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
392 ? NO : YES);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
393 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
394 break;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
395
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
396 case AC_DESTINATION_REALM:
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
397 /* Parse this AVP */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
398 CHECK_FCT_DO( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
399 ASSERT( ahdr->avp_value );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
400 dr_val = ahdr->avp_value;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
401 /* Compare the Destination-Realm AVP of the message with our identity */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
402 if (ahdr->avp_value->os.len != fd_g_config->cnf_diamrlm_len) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
403 is_dest_realm = NO;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
404 } else {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
405 is_dest_realm = (strncasecmp(fd_g_config->cnf_diamrlm, (char *)ahdr->avp_value->os.data, fd_g_config->cnf_diamrlm_len)
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
406 ? NO : YES);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
407 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
408 break;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
409
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
410 case AC_USER_NAME:
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
411 /* Parse this AVP */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
412 CHECK_FCT_DO( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
413 ASSERT( ahdr->avp_value );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
414 un = avp;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
415 un_val = ahdr->avp_value;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
416 break;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
417 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
418 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
419
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
420 if ((is_dest_host != UNKNOWN) && (is_dest_realm != UNKNOWN) && un)
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
421 break;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
422
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
423 /* Go to next AVP */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
424 CHECK_FCT_DO( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
425 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
426
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
427 /* OK, now decide what we do with the request */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
428
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
429 /* Handle the missing routing AVPs first */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
430 if ( is_dest_realm == UNKNOWN ) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
431 CHECK_FCT_DO( return_error( msg, "DIAMETER_COMMAND_UNSUPPORTED", "Non-routable message not supported (invalid bit ? missing Destination-Realm ?)", NULL), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
432 continue;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
433 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
434
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
435 /* If we are listed as Destination-Host */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
436 if (is_dest_host == YES) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
437 if (is_local_app == YES) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
438 /* Ok, give the message to the dispatch thread */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
439 CHECK_FCT_DO(fd_fifo_post(fd_g_local, &msg), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
440 } else {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
441 /* We don't support the application, reply an error */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
442 CHECK_FCT_DO( return_error( msg, "DIAMETER_APPLICATION_UNSUPPORTED", NULL, NULL), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
443 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
444 continue;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
445 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
446
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
447 /* If the message is explicitely for someone else */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
448 if ((is_dest_host == NO) || (is_dest_realm == NO)) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
449 if (fd_g_config->cnf_flags.no_fwd) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
450 CHECK_FCT_DO( return_error( msg, "DIAMETER_UNABLE_TO_DELIVER", "This peer is not an agent", NULL), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
451 continue;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
452 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
453 } else {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
454 /* Destination-Host was not set, and Destination-Realm is matching : we may handle or pass to a fellow peer */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
455
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
456 /* test for decorated NAI (draft-ietf-dime-nai-routing-04 section 4.4) */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
457 if (is_decorated_NAI(un_val)) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
458 /* Handle the decorated NAI */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
459 CHECK_FCT_DO( process_decorated_NAI(un_val, dr_val),
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
460 {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
461 /* If the process failed, we assume it is because of the AVP format */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
462 CHECK_FCT_DO( return_error( msg, "DIAMETER_INVALID_AVP_VALUE", "Failed to process decorated NAI", un), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
463 continue;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
464 } );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
465
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
466 /* We have transformed the AVP, now submit it again in the queue */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
467 CHECK_FCT_DO(fd_fifo_post(fd_g_incoming, &msg), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
468 continue;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
469 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
470
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
471 if (is_local_app == YES) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
472 /* Handle localy since we are able to */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
473 CHECK_FCT_DO(fd_fifo_post(fd_g_local, &msg), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
474 continue;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
475 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
476
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
477 if (fd_g_config->cnf_flags.no_fwd) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
478 /* We return an error */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
479 CHECK_FCT_DO( return_error( msg, "DIAMETER_APPLICATION_UNSUPPORTED", NULL, NULL), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
480 continue;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
481 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
482 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
483
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
484 /* From that point, for requests, we will call the registered callbacks, then forward to another peer */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
485
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
486 } else {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
487 /* The message is an answer */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
488 struct msg * qry;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
489
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
490 /* Retrieve the corresponding query and its origin */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
491 CHECK_FCT_DO( fd_msg_answ_getq( msg, &qry ), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
492 CHECK_FCT_DO( fd_msg_source_get( qry, &qry_src ), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
493
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
494 if ((!qry_src) && (!is_err)) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
495 /* The message is a normal answer to a request issued localy, we do not call the callbacks chain on it. */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
496 CHECK_FCT_DO(fd_fifo_post(fd_g_local, &msg), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
497 continue;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
498 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
499
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
500 /* From that point, for answers, we will call the registered callbacks, then pass it to the dispatch module or forward it */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
501 }
86
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
502
87
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
503 /* Call all registered callbacks for this message */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
504 {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
505 struct fd_list * li;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
506
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
507 CHECK_FCT_DO( pthread_rwlock_rdlock( &rt_fwd_lock ), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
508 pthread_cleanup_push( fd_cleanup_rwlock, &rt_fwd_lock );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
509
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
510 /* requests: dir = 1 & 2 => in order; answers = 3 & 2 => in reverse order */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
511 for ( li = (is_req ? rt_fwd_list.next : rt_fwd_list.prev) ; msg && (li != &rt_fwd_list) ; li = (is_req ? li->next : li->prev) ) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
512 struct rt_hdl * rh = (struct rt_hdl *)li;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
513
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
514 if (is_req && (rh->dir > RT_FWD_ALL))
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
515 break;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
516 if ((!is_req) && (rh->dir < RT_FWD_ALL))
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
517 break;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
518
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
519 /* Ok, call this cb */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
520 TRACE_DEBUG(ANNOYING, "Calling next FWD callback on %p : %p", msg, rh->rt_fwd_cb);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
521 CHECK_FCT_DO( (*rh->rt_fwd_cb)(rh->cbdata, &msg),
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
522 {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
523 TRACE_DEBUG(INFO, "A FWD routing callback returned an error, message discarded.");
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
524 fd_msg_dump_walk(INFO, msg);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
525 fd_msg_free(msg);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
526 msg = NULL;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
527 } );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
528 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
529
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
530 pthread_cleanup_pop(0);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
531 CHECK_FCT_DO( pthread_rwlock_unlock( &rt_fwd_lock ), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
532
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
533 /* If a callback has handled the message, we stop now */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
534 if (!msg)
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
535 continue;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
536 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
537
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
538 /* Now handle the message to the next step: either forward to another peer, or for local delivery */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
539 if (is_req || qry_src) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
540 CHECK_FCT_DO(fd_fifo_post(fd_g_outgoing, &msg), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
541 } else {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
542 CHECK_FCT_DO(fd_fifo_post(fd_g_local, &msg), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
543 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
544
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
545 /* We're done with this message */
86
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
546 } while (1);
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
547
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
548 fatal_error:
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
549 TRACE_DEBUG(INFO, "An error occurred in routing module! IN thread is terminating...");
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
550 CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, 0, NULL), );
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
551 return NULL;
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
552 }
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
553
87
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
554
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
555 /* The (routing-out) thread -- see description in freeDiameter.h */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
556 static void * routing_out_thr(void * arg)
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
557 {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
558 TRACE_ENTRY("%p", arg);
88
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
559 struct rt_data * rtd = NULL;
87
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
560
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
561 /* Set the thread name */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
562 if (arg) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
563 char buf[48];
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
564 snprintf(buf, sizeof(buf), "Routing-OUT %p", arg);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
565 fd_log_threadname ( buf );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
566 } else {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
567 fd_log_threadname ( "Routing-OUT" );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
568 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
569
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
570 /* Main thread loop */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
571 do {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
572 struct msg * msg;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
573 struct msg_hdr * hdr;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
574 int is_req = 0;
88
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
575 struct fd_list * li, *candidates;
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
576 struct avp * avp;
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
577 struct rtd_candidate * c;
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
578
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
579 /* If we loop'd with some undeleted routing data, destroy it */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
580 if (rtd != NULL)
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
581 fd_rtd_free(&rtd);
87
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
582
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
583 /* Test if we were told to stop */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
584 pthread_testcancel();
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
585
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
586 /* Get the next message from the ougoing queue */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
587 CHECK_FCT_DO( fd_fifo_get ( fd_g_outgoing, &msg ), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
588
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
589 if (TRACE_BOOL(FULL)) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
590 TRACE_DEBUG(FULL, "Picked next message:");
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
591 fd_msg_dump_one(FULL, msg);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
592 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
593
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
594 /* Read the message header */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
595 CHECK_FCT_DO( fd_msg_hdr(msg, &hdr), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
596 is_req = hdr->msg_flags & CMD_FLAG_REQUEST;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
597
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
598 /* For answers, the routing is very easy */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
599 if ( ! is_req ) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
600 struct msg * qry;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
601 char * qry_src = NULL;
88
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
602 struct msg_hdr * qry_hdr;
87
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
603 struct fd_peer * peer = NULL;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
604
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
605 /* Retrieve the corresponding query and its origin */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
606 CHECK_FCT_DO( fd_msg_answ_getq( msg, &qry ), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
607 CHECK_FCT_DO( fd_msg_source_get( qry, &qry_src ), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
608
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
609 ASSERT( qry_src ); /* if it is NULL, the message should have been in the LOCAL queue! */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
610
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
611 /* Find the peer corresponding to this name */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
612 CHECK_FCT_DO( fd_peer_getbyid( qry_src, (void *) &peer ), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
613 if ((!peer) || (peer->p_hdr.info.runtime.pir_state != STATE_OPEN)) {
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
614 TRACE_DEBUG(INFO, "Unable to forward answer message to peer '%s', deleted or not in OPEN state.", qry_src);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
615 fd_msg_dump_walk(INFO, msg);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
616 fd_msg_free(msg);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
617 continue;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
618 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
619
88
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
620 /* We must restore the hop-by-hop id */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
621 CHECK_FCT_DO( fd_msg_hdr(qry, &qry_hdr), goto fatal_error );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
622 hdr->msg_hbhid = qry_hdr->msg_hbhid;
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
623
87
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
624 /* Push the message into this peer */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
625 CHECK_FCT_DO( fd_out_send(&msg, NULL, peer), goto fatal_error );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
626
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
627 /* We're done with this answer */
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
628 continue;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
629 }
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
630
88
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
631 /* From that point, the message is a request */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
632
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
633 /* Get the routing data out of the message if any (in case of re-transmit) */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
634 CHECK_FCT_DO( fd_msg_rt_get ( msg, &rtd ), goto fatal_error );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
635
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
636 /* If there is no routing data already, let's create it */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
637 if (rtd == NULL) {
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
638 CHECK_FCT_DO( fd_rtd_init(&rtd), goto fatal_error );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
639
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
640 /* Add all peers in OPEN state */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
641 CHECK_FCT_DO( pthread_rwlock_wrlock(&fd_g_activ_peers_rw), goto fatal_error );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
642 for (li = fd_g_activ_peers.next; li != &fd_g_activ_peers; li = li->next) {
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
643 struct fd_peer * p = (struct fd_peer *)li->o;
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
644 CHECK_FCT_DO( fd_rtd_candidate_add(rtd, p->p_hdr.info.pi_diamid), goto fatal_error);
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
645 }
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
646 CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_activ_peers_rw), goto fatal_error );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
647
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
648 /* Now let's remove all peers from the Route-Records */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
649 CHECK_FCT_DO( fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, &avp, NULL), goto fatal_error );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
650 while (avp) {
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
651 struct avp_hdr * ahdr;
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
652 CHECK_FCT_DO( fd_msg_avp_hdr( avp, &ahdr ), goto fatal_error );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
653
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
654 if ((ahdr->avp_code == AC_ROUTE_RECORD) && (! (ahdr->avp_flags & AVP_FLAG_VENDOR)) ) {
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
655 /* Parse this AVP */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
656 CHECK_FCT_DO( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ), goto fatal_error );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
657 ASSERT( ahdr->avp_value );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
658 /* Remove this value from the list */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
659 fd_rtd_candidate_del(rtd, (char *)ahdr->avp_value->os.data, ahdr->avp_value->os.len);
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
660 }
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
661
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
662 /* Go to next AVP */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
663 CHECK_FCT_DO( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL), goto fatal_error );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
664 }
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
665 }
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
666
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
667 /* Note: we reset the scores and pass the message to the callbacks, maybe we could re-use the saved scores when we have received an error ? */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
668
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
669 /* Ok, we have our list in rtd now, let's (re)initialize the scores */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
670 fd_rtd_candidate_extract(rtd, &candidates);
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
671
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
672 /* Pass the list to registered callbacks (even if it is empty) */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
673 {
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
674 CHECK_FCT_DO( pthread_rwlock_rdlock( &rt_out_lock ), goto fatal_error );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
675 pthread_cleanup_push( fd_cleanup_rwlock, &rt_out_lock );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
676
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
677 /* We call the cb by reverse priority order */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
678 for ( li = rt_out_list.prev ; li != &rt_out_list ; li = li->prev ) {
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
679 struct rt_hdl * rh = (struct rt_hdl *)li;
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
680
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
681 TRACE_DEBUG(ANNOYING, "Calling next OUT callback on %p : %p (prio %d)", msg, rh->rt_out_cb, rh->prio);
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
682 CHECK_FCT_DO( (*rh->rt_out_cb)(rh->cbdata, msg, candidates),
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
683 {
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
684 TRACE_DEBUG(INFO, "An OUT routing callback returned an error ! Message discarded.");
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
685 fd_msg_dump_walk(INFO, msg);
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
686 fd_msg_free(msg);
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
687 msg = NULL;
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
688 break;
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
689 } );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
690 }
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
691
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
692 pthread_cleanup_pop(0);
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
693 CHECK_FCT_DO( pthread_rwlock_unlock( &rt_out_lock ), goto fatal_error );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
694
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
695 /* If an error occurred, skip to the next message */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
696 if (!msg)
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
697 continue;
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
698 }
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
699
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
700 /* Order the candidate peers by score attributed by the callbacks */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
701 CHECK_FCT_DO( fd_rtd_candidate_reorder(candidates), goto fatal_error );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
702
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
703 /* Save the routing information in the message */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
704 CHECK_FCT_DO( fd_msg_rt_associate ( msg, &rtd ), goto fatal_error );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
705
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
706 /* Now try sending the message */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
707 for (li = candidates->prev; li != candidates; li = li->prev) {
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
708 struct fd_peer * peer;
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
709
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
710 c = (struct rtd_candidate *) li;
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
711
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
712 /* Stop when we have reached the end of valid candidates */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
713 if (c->score < 0)
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
714 break;
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
715
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
716 /* Search for the peer */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
717 CHECK_FCT_DO( fd_peer_getbyid( c->diamid, (void *)&peer ), goto fatal_error );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
718
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
719 if (peer && (peer->p_hdr.info.runtime.pir_state == STATE_OPEN)) {
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
720 /* Send to this one */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
721 CHECK_FCT_DO( fd_out_send(&msg, NULL, peer), continue );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
722 /* If the sending was successful */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
723 break;
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
724 }
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
725 }
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
726
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
727 /* If the message has not been sent, return an error */
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
728 if (msg) {
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
729 TRACE_DEBUG(INFO, "Could not send the following message, replying with UNABLE_TO_DELIVER");
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
730 fd_msg_dump_walk(INFO, msg);
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
731 return_error( msg, "DIAMETER_UNABLE_TO_DELIVER", "No suitable candidate to route the message to", NULL);
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
732 }
87
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
733
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
734 /* We're done with this message */
88
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
735
87
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
736 } while (1);
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
737
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
738 fatal_error:
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
739 TRACE_DEBUG(INFO, "An error occurred in routing module! OUT thread is terminating...");
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
740 CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, 0, NULL), );
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
741 return NULL;
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
742 }
82
b6344f1d521a Some cleanups
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 41
diff changeset
743
89
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
744 /* First OUT callback: prevent sending to peers that do not support the message application */
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
745 static int dont_send_if_no_common_app(void * cbdata, struct msg * msg, struct fd_list * candidates)
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
746 {
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
747 struct fd_list * li;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
748 struct msg_hdr * hdr;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
749
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
750 TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
751 CHECK_PARAMS(msg && candidates);
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
752
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
753 CHECK_FCT( fd_msg_hdr(msg, &hdr) );
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
754
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
755 /* For Base Diameter Protocol, every peer is supposed to support it, so skip */
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
756 if (hdr->msg_appl == 0)
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
757 return 0;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
758
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
759 /* Otherwise, check that the peers support the application */
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
760 for (li = candidates->next; li != candidates; li = li->next) {
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
761 struct rtd_candidate *c = (struct rtd_candidate *) li;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
762 struct fd_peer * peer;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
763 struct fd_app *found;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
764 CHECK_FCT( fd_peer_getbyid( c->diamid, (void *)&peer ) );
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
765 if (peer && (peer->p_hdr.info.runtime.pir_relay == 0)) {
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
766 /* Check if the remote peer advertised the message's appli */
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
767 CHECK_FCT( fd_app_check(&peer->p_hdr.info.runtime.pir_apps, hdr->msg_appl, &found) );
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
768 if (!found)
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
769 c->score += FD_SCORE_NO_DELIVERY;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
770 }
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
771 }
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
772
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
773 return 0;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
774 }
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
775
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
776 /* Second OUT callback: Detect if the Destination-Host and Destination-Realm match the peer */
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
777 static int score_destination_avp(void * cbdata, struct msg * msg, struct fd_list * candidates)
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
778 {
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
779 struct fd_list * li;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
780 struct avp * avp;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
781 union avp_value *dh = NULL, *dr = NULL;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
782
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
783 TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
784 CHECK_PARAMS(msg && candidates);
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
785
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
786 /* Search the Destination-Host and Destination-Realm AVPs -- we could also use fd_msg_search_avp here, but this one is slightly more efficient */
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
787 CHECK_FCT( fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, &avp, NULL) );
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
788 while (avp) {
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
789 struct avp_hdr * ahdr;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
790 CHECK_FCT( fd_msg_avp_hdr( avp, &ahdr ) );
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
791
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
792 if (! (ahdr->avp_flags & AVP_FLAG_VENDOR)) {
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
793 switch (ahdr->avp_code) {
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
794 case AC_DESTINATION_HOST:
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
795 /* Parse this AVP */
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
796 CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ) );
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
797 ASSERT( ahdr->avp_value );
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
798 dh = ahdr->avp_value;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
799 break;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
800
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
801 case AC_DESTINATION_REALM:
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
802 /* Parse this AVP */
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
803 CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ) );
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
804 ASSERT( ahdr->avp_value );
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
805 dr = ahdr->avp_value;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
806 break;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
807 }
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
808 }
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
809
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
810 if (dh && dr)
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
811 break;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
812
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
813 /* Go to next AVP */
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
814 CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) );
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
815 }
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
816
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
817 /* Now, check each candidate against these AVP values */
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
818 for (li = candidates->next; li != candidates; li = li->next) {
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
819 struct rtd_candidate *c = (struct rtd_candidate *) li;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
820 struct fd_peer * peer;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
821 CHECK_FCT( fd_peer_getbyid( c->diamid, (void *)&peer ) );
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
822 if (peer) {
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
823 if (dh
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
824 && (dh->os.len == strlen(peer->p_hdr.info.pi_diamid))
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
825 && (strncasecmp(peer->p_hdr.info.pi_diamid, dh->os.data, dh->os.len) == 0)) {
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
826 /* The candidate is the Destination-Host */
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
827 c->score += FD_SCORE_FINALDEST;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
828 } else {
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
829 if (dr && peer->p_hdr.info.runtime.pir_realm
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
830 && (dr->os.len == strlen(peer->p_hdr.info.runtime.pir_realm))
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
831 && (strncasecmp(peer->p_hdr.info.runtime.pir_realm, dr->os.data, dr->os.len) == 0)) {
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
832 /* The candidate's realm matchs the Destination-Realm */
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
833 c->score += FD_SCORE_REALM;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
834 }
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
835 }
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
836 }
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
837 }
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
838
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
839 return 0;
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
840 }
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
841
88
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
842 static pthread_t rt_out = (pthread_t)NULL;
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
843 static pthread_t rt_in = (pthread_t)NULL;
86
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
844
82
b6344f1d521a Some cleanups
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 41
diff changeset
845 /* Initialize the routing module */
b6344f1d521a Some cleanups
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 41
diff changeset
846 int fd_rt_init(void)
b6344f1d521a Some cleanups
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 41
diff changeset
847 {
88
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
848 CHECK_POSIX( pthread_create( &rt_out, NULL, routing_out_thr, NULL) );
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
849 CHECK_POSIX( pthread_create( &rt_in, NULL, routing_in_thr, NULL) );
87
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
850
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 86
diff changeset
851 /* Later: TODO("Set the thresholds for the IN and OUT queues to create more routing threads as needed"); */
89
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
852
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
853 /* Register the built-in callbacks */
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
854 CHECK_FCT( fd_rt_out_register( dont_send_if_no_common_app, NULL, 10, NULL ) );
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
855 CHECK_FCT( fd_rt_out_register( score_destination_avp, NULL, 10, NULL ) );
3f8b437bcb66 Added some default routing handlers
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 88
diff changeset
856
88
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
857 return 0;
82
b6344f1d521a Some cleanups
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 41
diff changeset
858 }
b6344f1d521a Some cleanups
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 41
diff changeset
859
b6344f1d521a Some cleanups
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 41
diff changeset
860 /* Terminate the routing module */
b6344f1d521a Some cleanups
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 41
diff changeset
861 int fd_rt_fini(void)
b6344f1d521a Some cleanups
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 41
diff changeset
862 {
88
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
863 CHECK_FCT_DO( fd_thr_term(&rt_in ), /* continue */);
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
864 CHECK_FCT_DO( fd_thr_term(&rt_out), /* continue */);
9e2db1647d6f Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 87
diff changeset
865 return 0;
82
b6344f1d521a Some cleanups
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 41
diff changeset
866 }
85
e5fcd672caff Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 82
diff changeset
867
e5fcd672caff Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 82
diff changeset
868
86
e3e22d89e023 Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents: 85
diff changeset
869
"Welcome to our mercurial repository"