Mercurial > hg > freeDiameter
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 |
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 | 193 /* Test if a User-Name AVP contains a Decorated NAI -- RFC4282, draft-ietf-dime-nai-routing-04 */ |
194 static int is_decorated_NAI(union avp_value * un) | |
195 { | |
196 int i; | |
197 TRACE_ENTRY("%p", un); | |
198 | |
199 /* If there was no User-Name, we return false */ | |
200 if (un == NULL) | |
201 return 0; | |
202 | |
203 /* Search if there is a '!' before any '@' -- do we need to check it contains a '.' ? */ | |
204 for (i = 0; i < un->os.len; i++) { | |
205 if ( un->os.data[i] == (unsigned char) '!' ) | |
206 return 1; | |
207 if ( un->os.data[i] == (unsigned char) '@' ) | |
208 break; | |
209 if ( un->os.data[i] == (unsigned char) '\\' ) | |
210 i++; /* next one was escaped */ | |
211 } | |
212 | |
213 return 0; | |
214 } | |
215 | |
216 /* Create new User-Name and Destination-Realm values */ | |
217 static int process_decorated_NAI(union avp_value * un, union avp_value * dr) | |
218 { | |
219 int i, at_idx = 0, sep_idx = 0; | |
220 unsigned char * old_un; | |
221 TRACE_ENTRY("%p %p", un, dr); | |
222 CHECK_PARAMS(un && dr); | |
223 | |
224 /* Save the decorated User-Name, for example 'homerealm.example.net!user@otherrealm.example.net' */ | |
225 old_un = un->os.data; | |
226 | |
227 /* Search the positions of the first '!' and the '@' in the string */ | |
228 for (i = 0; i < un->os.len; i++) { | |
229 if ( (!sep_idx) && (old_un[i] == (unsigned char) '!') ) | |
230 sep_idx = i; | |
231 if ( old_un[i] == (unsigned char) '@' ) { | |
232 at_idx = i; | |
233 break; | |
234 } | |
235 if ( un->os.data[i] == (unsigned char) '\\' ) | |
236 i++; /* next one is escaped */ | |
237 } | |
238 | |
239 CHECK_PARAMS( 0 < sep_idx < at_idx < un->os.len); | |
240 | |
241 /* Create the new User-Name value */ | |
242 CHECK_MALLOC( un->os.data = malloc( at_idx ) ); | |
243 memcpy( un->os.data, old_un + sep_idx + 1, at_idx - sep_idx ); /* user@ */ | |
244 memcpy( un->os.data + at_idx - sep_idx, old_un, sep_idx ); /* homerealm.example.net */ | |
245 | |
246 /* Create the new Destination-Realm value */ | |
247 CHECK_MALLOC( dr->os.data = realloc(dr->os.data, sep_idx) ); | |
248 memcpy( dr->os.data, old_un, sep_idx ); | |
249 dr->os.len = sep_idx; | |
250 | |
251 TRACE_DEBUG(FULL, "Processed Decorated NAI '%.*s' into '%.*s' (%.*s)", | |
252 un->os.len, old_un, | |
253 at_idx, un->os.data, | |
254 dr->os.len, dr->os.data); | |
255 | |
256 un->os.len = at_idx; | |
257 free(old_un); | |
258 | |
259 return 0; | |
260 } | |
261 | |
262 | |
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 | 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 | 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 | 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 | 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 | 352 /* If it is a request, we must analyze its content to decide what we do with it */ |
353 if (is_req) { | |
354 struct avp * avp, *un = NULL; | |
355 union avp_value * un_val = NULL, *dr_val = NULL; | |
356 enum status { UNKNOWN, YES, NO }; | |
357 /* Are we Destination-Host? */ | |
358 enum status is_dest_host = UNKNOWN; | |
359 /* Are we Destination-Realm? */ | |
360 enum status is_dest_realm = UNKNOWN; | |
361 /* Do we support the application of the message? */ | |
362 enum status is_local_app = UNKNOWN; | |
363 | |
364 /* Check if we have local support for the message application */ | |
365 if ( (hdr->msg_appl == 0) || (hdr->msg_appl == AI_RELAY) ) { | |
366 TRACE_DEBUG(INFO, "Received a routable message with application id 0, returning DIAMETER_APPLICATION_UNSUPPORTED"); | |
367 CHECK_FCT_DO( return_error( msg, "DIAMETER_APPLICATION_UNSUPPORTED", "Routable message with application id 0 or relay", NULL), goto fatal_error ); | |
368 continue; | |
369 } else { | |
370 struct fd_app * app; | |
371 CHECK_FCT_DO( fd_app_check(&fd_g_config->cnf_apps, hdr->msg_appl, &app), goto fatal_error ); | |
372 is_local_app = (app ? YES : NO); | |
373 } | |
374 | |
375 /* Parse the message for Dest-Host and Dest-Realm */ | |
376 CHECK_FCT_DO( fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, &avp, NULL), goto fatal_error ); | |
377 while (avp) { | |
378 struct avp_hdr * ahdr; | |
379 CHECK_FCT_DO( fd_msg_avp_hdr( avp, &ahdr ), goto fatal_error ); | |
380 | |
381 if (! (ahdr->avp_flags & AVP_FLAG_VENDOR)) { | |
382 switch (ahdr->avp_code) { | |
383 case AC_DESTINATION_HOST: | |
384 /* Parse this AVP */ | |
385 CHECK_FCT_DO( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ), goto fatal_error ); | |
386 ASSERT( ahdr->avp_value ); | |
387 /* Compare the Destination-Host AVP of the message with our identity */ | |
388 if (ahdr->avp_value->os.len != fd_g_config->cnf_diamid_len) { | |
389 is_dest_host = NO; | |
390 } else { | |
391 is_dest_host = (strncasecmp(fd_g_config->cnf_diamid, (char *)ahdr->avp_value->os.data, fd_g_config->cnf_diamid_len) | |
392 ? NO : YES); | |
393 } | |
394 break; | |
395 | |
396 case AC_DESTINATION_REALM: | |
397 /* Parse this AVP */ | |
398 CHECK_FCT_DO( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ), goto fatal_error ); | |
399 ASSERT( ahdr->avp_value ); | |
400 dr_val = ahdr->avp_value; | |
401 /* Compare the Destination-Realm AVP of the message with our identity */ | |
402 if (ahdr->avp_value->os.len != fd_g_config->cnf_diamrlm_len) { | |
403 is_dest_realm = NO; | |
404 } else { | |
405 is_dest_realm = (strncasecmp(fd_g_config->cnf_diamrlm, (char *)ahdr->avp_value->os.data, fd_g_config->cnf_diamrlm_len) | |
406 ? NO : YES); | |
407 } | |
408 break; | |
409 | |
410 case AC_USER_NAME: | |
411 /* Parse this AVP */ | |
412 CHECK_FCT_DO( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ), goto fatal_error ); | |
413 ASSERT( ahdr->avp_value ); | |
414 un = avp; | |
415 un_val = ahdr->avp_value; | |
416 break; | |
417 } | |
418 } | |
419 | |
420 if ((is_dest_host != UNKNOWN) && (is_dest_realm != UNKNOWN) && un) | |
421 break; | |
422 | |
423 /* Go to next AVP */ | |
424 CHECK_FCT_DO( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL), goto fatal_error ); | |
425 } | |
426 | |
427 /* OK, now decide what we do with the request */ | |
428 | |
429 /* Handle the missing routing AVPs first */ | |
430 if ( is_dest_realm == UNKNOWN ) { | |
431 CHECK_FCT_DO( return_error( msg, "DIAMETER_COMMAND_UNSUPPORTED", "Non-routable message not supported (invalid bit ? missing Destination-Realm ?)", NULL), goto fatal_error ); | |
432 continue; | |
433 } | |
434 | |
435 /* If we are listed as Destination-Host */ | |
436 if (is_dest_host == YES) { | |
437 if (is_local_app == YES) { | |
438 /* Ok, give the message to the dispatch thread */ | |
439 CHECK_FCT_DO(fd_fifo_post(fd_g_local, &msg), goto fatal_error ); | |
440 } else { | |
441 /* We don't support the application, reply an error */ | |
442 CHECK_FCT_DO( return_error( msg, "DIAMETER_APPLICATION_UNSUPPORTED", NULL, NULL), goto fatal_error ); | |
443 } | |
444 continue; | |
445 } | |
446 | |
447 /* If the message is explicitely for someone else */ | |
448 if ((is_dest_host == NO) || (is_dest_realm == NO)) { | |
449 if (fd_g_config->cnf_flags.no_fwd) { | |
450 CHECK_FCT_DO( return_error( msg, "DIAMETER_UNABLE_TO_DELIVER", "This peer is not an agent", NULL), goto fatal_error ); | |
451 continue; | |
452 } | |
453 } else { | |
454 /* Destination-Host was not set, and Destination-Realm is matching : we may handle or pass to a fellow peer */ | |
455 | |
456 /* test for decorated NAI (draft-ietf-dime-nai-routing-04 section 4.4) */ | |
457 if (is_decorated_NAI(un_val)) { | |
458 /* Handle the decorated NAI */ | |
459 CHECK_FCT_DO( process_decorated_NAI(un_val, dr_val), | |
460 { | |
461 /* If the process failed, we assume it is because of the AVP format */ | |
462 CHECK_FCT_DO( return_error( msg, "DIAMETER_INVALID_AVP_VALUE", "Failed to process decorated NAI", un), goto fatal_error ); | |
463 continue; | |
464 } ); | |
465 | |
466 /* We have transformed the AVP, now submit it again in the queue */ | |
467 CHECK_FCT_DO(fd_fifo_post(fd_g_incoming, &msg), goto fatal_error ); | |
468 continue; | |
469 } | |
470 | |
471 if (is_local_app == YES) { | |
472 /* Handle localy since we are able to */ | |
473 CHECK_FCT_DO(fd_fifo_post(fd_g_local, &msg), goto fatal_error ); | |
474 continue; | |
475 } | |
476 | |
477 if (fd_g_config->cnf_flags.no_fwd) { | |
478 /* We return an error */ | |
479 CHECK_FCT_DO( return_error( msg, "DIAMETER_APPLICATION_UNSUPPORTED", NULL, NULL), goto fatal_error ); | |
480 continue; | |
481 } | |
482 } | |
483 | |
484 /* From that point, for requests, we will call the registered callbacks, then forward to another peer */ | |
485 | |
486 } else { | |
487 /* The message is an answer */ | |
488 struct msg * qry; | |
489 | |
490 /* Retrieve the corresponding query and its origin */ | |
491 CHECK_FCT_DO( fd_msg_answ_getq( msg, &qry ), goto fatal_error ); | |
492 CHECK_FCT_DO( fd_msg_source_get( qry, &qry_src ), goto fatal_error ); | |
493 | |
494 if ((!qry_src) && (!is_err)) { | |
495 /* The message is a normal answer to a request issued localy, we do not call the callbacks chain on it. */ | |
496 CHECK_FCT_DO(fd_fifo_post(fd_g_local, &msg), goto fatal_error ); | |
497 continue; | |
498 } | |
499 | |
500 /* From that point, for answers, we will call the registered callbacks, then pass it to the dispatch module or forward it */ | |
501 } | |
86
e3e22d89e023
Started routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
85
diff
changeset
|
502 |
87 | 503 /* Call all registered callbacks for this message */ |
504 { | |
505 struct fd_list * li; | |
506 | |
507 CHECK_FCT_DO( pthread_rwlock_rdlock( &rt_fwd_lock ), goto fatal_error ); | |
508 pthread_cleanup_push( fd_cleanup_rwlock, &rt_fwd_lock ); | |
509 | |
510 /* requests: dir = 1 & 2 => in order; answers = 3 & 2 => in reverse order */ | |
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) ) { | |
512 struct rt_hdl * rh = (struct rt_hdl *)li; | |
513 | |
514 if (is_req && (rh->dir > RT_FWD_ALL)) | |
515 break; | |
516 if ((!is_req) && (rh->dir < RT_FWD_ALL)) | |
517 break; | |
518 | |
519 /* Ok, call this cb */ | |
520 TRACE_DEBUG(ANNOYING, "Calling next FWD callback on %p : %p", msg, rh->rt_fwd_cb); | |
521 CHECK_FCT_DO( (*rh->rt_fwd_cb)(rh->cbdata, &msg), | |
522 { | |
523 TRACE_DEBUG(INFO, "A FWD routing callback returned an error, message discarded."); | |
524 fd_msg_dump_walk(INFO, msg); | |
525 fd_msg_free(msg); | |
526 msg = NULL; | |
527 } ); | |
528 } | |
529 | |
530 pthread_cleanup_pop(0); | |
531 CHECK_FCT_DO( pthread_rwlock_unlock( &rt_fwd_lock ), goto fatal_error ); | |
532 | |
533 /* If a callback has handled the message, we stop now */ | |
534 if (!msg) | |
535 continue; | |
536 } | |
537 | |
538 /* Now handle the message to the next step: either forward to another peer, or for local delivery */ | |
539 if (is_req || qry_src) { | |
540 CHECK_FCT_DO(fd_fifo_post(fd_g_outgoing, &msg), goto fatal_error ); | |
541 } else { | |
542 CHECK_FCT_DO(fd_fifo_post(fd_g_local, &msg), goto fatal_error ); | |
543 } | |
544 | |
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 | 554 |
555 /* The (routing-out) thread -- see description in freeDiameter.h */ | |
556 static void * routing_out_thr(void * arg) | |
557 { | |
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 | 560 |
561 /* Set the thread name */ | |
562 if (arg) { | |
563 char buf[48]; | |
564 snprintf(buf, sizeof(buf), "Routing-OUT %p", arg); | |
565 fd_log_threadname ( buf ); | |
566 } else { | |
567 fd_log_threadname ( "Routing-OUT" ); | |
568 } | |
569 | |
570 /* Main thread loop */ | |
571 do { | |
572 struct msg * msg; | |
573 struct msg_hdr * hdr; | |
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 | 582 |
583 /* Test if we were told to stop */ | |
584 pthread_testcancel(); | |
585 | |
586 /* Get the next message from the ougoing queue */ | |
587 CHECK_FCT_DO( fd_fifo_get ( fd_g_outgoing, &msg ), goto fatal_error ); | |
588 | |
589 if (TRACE_BOOL(FULL)) { | |
590 TRACE_DEBUG(FULL, "Picked next message:"); | |
591 fd_msg_dump_one(FULL, msg); | |
592 } | |
593 | |
594 /* Read the message header */ | |
595 CHECK_FCT_DO( fd_msg_hdr(msg, &hdr), goto fatal_error ); | |
596 is_req = hdr->msg_flags & CMD_FLAG_REQUEST; | |
597 | |
598 /* For answers, the routing is very easy */ | |
599 if ( ! is_req ) { | |
600 struct msg * qry; | |
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 | 603 struct fd_peer * peer = NULL; |
604 | |
605 /* Retrieve the corresponding query and its origin */ | |
606 CHECK_FCT_DO( fd_msg_answ_getq( msg, &qry ), goto fatal_error ); | |
607 CHECK_FCT_DO( fd_msg_source_get( qry, &qry_src ), goto fatal_error ); | |
608 | |
609 ASSERT( qry_src ); /* if it is NULL, the message should have been in the LOCAL queue! */ | |
610 | |
611 /* Find the peer corresponding to this name */ | |
612 CHECK_FCT_DO( fd_peer_getbyid( qry_src, (void *) &peer ), goto fatal_error ); | |
613 if ((!peer) || (peer->p_hdr.info.runtime.pir_state != STATE_OPEN)) { | |
614 TRACE_DEBUG(INFO, "Unable to forward answer message to peer '%s', deleted or not in OPEN state.", qry_src); | |
615 fd_msg_dump_walk(INFO, msg); | |
616 fd_msg_free(msg); | |
617 continue; | |
618 } | |
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 | 624 /* Push the message into this peer */ |
625 CHECK_FCT_DO( fd_out_send(&msg, NULL, peer), goto fatal_error ); | |
626 | |
627 /* We're done with this answer */ | |
628 continue; | |
629 } | |
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 | 733 |
734 /* We're done with this message */ | |
88
9e2db1647d6f
Completed routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
87
diff
changeset
|
735 |
87 | 736 } while (1); |
737 | |
738 fatal_error: | |
739 TRACE_DEBUG(INFO, "An error occurred in routing module! OUT thread is terminating..."); | |
740 CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, 0, NULL), ); | |
741 return NULL; | |
742 } | |
82 | 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 | 845 /* Initialize the routing module */ |
846 int fd_rt_init(void) | |
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 | 850 |
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 | 858 } |
859 | |
860 /* Terminate the routing module */ | |
861 int fd_rt_fini(void) | |
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 | 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 |