Changeset 86:e3e22d89e023 in freeDiameter
- Timestamp:
- Dec 3, 2009, 5:36:35 PM (14 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
freeDiameter/peers.c
r78 r86 159 159 } 160 160 161 /* Search for a peer */ 162 int fd_peer_getbyid( char * diamid, struct peer_hdr ** peer ) 163 { 164 struct fd_list * li; 165 166 TRACE_ENTRY("%p %p", diamid, peer); 167 CHECK_PARAMS( diamid && peer ); 168 169 *peer = NULL; 170 171 /* Search in the list */ 172 CHECK_POSIX( pthread_rwlock_rdlock(&fd_g_peers_rw) ); 173 for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { 174 struct fd_peer * next = (struct fd_peer *)li; 175 int cmp = strcasecmp( diamid, next->p_hdr.info.pi_diamid ); 176 if (cmp > 0) 177 continue; 178 if (cmp == 0) 179 *peer = &next->p_hdr; 180 break; 181 } 182 CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) ); 183 184 return 0; 185 } 186 161 187 162 188 #define free_null( _v ) \ -
freeDiameter/routing.c
r85 r86 36 36 #include "fD.h" 37 37 38 /********************************************************************************/ 39 /* First part : handling the extensions callbacks */ 40 /********************************************************************************/ 41 42 /* Lists of the callbacks, and locks to protect them */ 43 static pthread_rwlock_t rt_fwd_lock = PTHREAD_RWLOCK_INITIALIZER; 44 static struct fd_list rt_fwd_list = FD_LIST_INITIALIZER_O(rt_fwd_list, &rt_fwd_lock); 45 46 static pthread_rwlock_t rt_out_lock = PTHREAD_RWLOCK_INITIALIZER; 47 static struct fd_list rt_out_list = FD_LIST_INITIALIZER_O(rt_out_list, &rt_out_lock); 48 49 /* Items in the lists are the same */ 50 struct rt_hdl { 51 struct fd_list chain; /* link in the rt_fwd_list or rt_out_list */ 52 void * cbdata; /* the registered data */ 53 union { 54 int order; /* This value is used to sort the list */ 55 int dir; /* It is the direction for FWD handlers */ 56 int prio; /* and the priority for OUT handlers */ 57 }; 58 union { 59 int (*rt_fwd_cb)(void * cbdata, struct msg ** msg); 60 int (*rt_out_cb)(void * cbdata, struct msg * msg, struct fd_list * candidates); 61 }; 62 }; 63 64 /* Add a new entry in the list */ 65 static int add_ordered(struct rt_hdl * new, struct fd_list * list) 66 { 67 /* The list is ordered by prio parameter */ 68 struct fd_list * li; 69 70 CHECK_POSIX( pthread_rwlock_wrlock(list->o) ); 71 72 for (li = list->next; li != list; li = li->next) { 73 struct rt_hdl * h = (struct rt_hdl *) li; 74 if (new->order <= h->order) 75 break; 76 } 77 78 fd_list_insert_before(li, &new->chain); 79 80 CHECK_POSIX( pthread_rwlock_unlock(list->o) ); 81 } 82 83 /* Register a new FWD callback */ 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 ) 85 { 86 struct rt_hdl * new; 87 88 TRACE_ENTRY("%p %p %d %p", rt_fwd_cb, cbdata, dir, handler); 89 CHECK_PARAMS( rt_fwd_cb ); 90 CHECK_PARAMS( (dir >= RT_FWD_REQ) && ( dir <= RT_FWD_ANS) ); 91 92 /* Create a new container */ 93 CHECK_MALLOC(new = malloc(sizeof(struct rt_hdl))); 94 memset(new, 0, sizeof(struct rt_hdl)); 95 96 /* Write the content */ 97 fd_list_init(&new->chain, NULL); 98 new->cbdata = cbdata; 99 new->dir = dir; 100 new->rt_fwd_cb = rt_fwd_cb; 101 102 /* Save this in the list */ 103 CHECK_FCT( add_ordered(new, &rt_fwd_list) ); 104 105 /* Give it back to the extension if needed */ 106 if (handler) 107 *handler = (void *)new; 108 109 return 0; 110 } 111 112 /* Remove it */ 113 int fd_rt_fwd_unregister ( struct fd_rt_fwd_hdl * handler, void ** cbdata ) 114 { 115 struct rt_hdl * del; 116 TRACE_ENTRY( "%p %p", handler, cbdata); 117 CHECK_PARAMS( handler ); 118 119 del = (struct rt_hdl *)handler; 120 CHECK_PARAMS( del->chain.head == &rt_fwd_list ); 121 122 /* Unlink */ 123 CHECK_POSIX( pthread_rwlock_wrlock(&rt_fwd_lock) ); 124 fd_list_unlink(&del->chain); 125 CHECK_POSIX( pthread_rwlock_unlock(&rt_fwd_lock) ); 126 127 if (cbdata) 128 *cbdata = del->cbdata; 129 130 free(del); 131 return 0; 132 } 133 134 /* Register a new OUT callback */ 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 ) 136 { 137 struct rt_hdl * new; 138 139 TRACE_ENTRY("%p %p %d %p", rt_out_cb, cbdata, priority, handler); 140 CHECK_PARAMS( rt_out_cb ); 141 142 /* Create a new container */ 143 CHECK_MALLOC(new = malloc(sizeof(struct rt_hdl))); 144 memset(new, 0, sizeof(struct rt_hdl)); 145 146 /* Write the content */ 147 fd_list_init(&new->chain, NULL); 148 new->cbdata = cbdata; 149 new->prio = priority; 150 new->rt_out_cb = rt_out_cb; 151 152 /* Save this in the list */ 153 CHECK_FCT( add_ordered(new, &rt_out_list) ); 154 155 /* Give it back to the extension if needed */ 156 if (handler) 157 *handler = (void *)new; 158 159 return 0; 160 } 161 162 /* Remove it */ 163 int fd_rt_out_unregister ( struct fd_rt_out_hdl * handler, void ** cbdata ) 164 { 165 struct rt_hdl * del; 166 TRACE_ENTRY( "%p %p", handler, cbdata); 167 CHECK_PARAMS( handler ); 168 169 del = (struct rt_hdl *)handler; 170 CHECK_PARAMS( del->chain.head == &rt_out_list ); 171 172 /* Unlink */ 173 CHECK_POSIX( pthread_rwlock_wrlock(&rt_out_lock) ); 174 fd_list_unlink(&del->chain); 175 CHECK_POSIX( pthread_rwlock_unlock(&rt_out_lock) ); 176 177 if (cbdata) 178 *cbdata = del->cbdata; 179 180 free(del); 181 return 0; 182 } 183 184 /********************************************************************************/ 185 /* Second part : the routing threads */ 186 /********************************************************************************/ 187 188 /* Note: in the first version, we only create one thread of each kind. 189 We could improve the scalability by using the threshold feature of the queues fd_g_incoming and fd_g_outgoing 190 ( fd_g_local is managed by the dispatch thread ) to create additional threads if a queue is filling up. 191 */ 192 193 /* Function to return an error to an incoming request */ 194 static int return_error(struct msg * msg, char * error_code) 195 { 196 struct fd_peer * peer; 197 198 /* Get the source of the message */ 199 { 200 char * id; 201 CHECK_FCT( fd_msg_source_get( msg, &id ) ); 202 203 /* Search the peer with this id */ 204 CHECK_FCT( fd_peer_getbyid( id, (void *)&peer ) ); 205 206 if (!peer) { 207 TRACE_DEBUG(INFO, "Unable to send error '%s' to deleted peer '%s' in reply to:", error_code, id); 208 fd_msg_dump_walk(INFO, msg); 209 fd_msg_free(msg); 210 return 0; 211 } 212 } 213 214 /* Create the error message */ 215 CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, &msg, MSGFL_ANSW_ERROR ) ); 216 217 /* Set the error code */ 218 CHECK_FCT( fd_msg_rescode_set(msg, error_code, NULL, NULL, 1 ) ); 219 220 /* Send the answer */ 221 CHECK_FCT( fd_out_send(&msg, NULL, peer) ); 222 223 /* Done */ 224 return 0; 225 } 226 227 228 /* The (routing-in) thread -- see description in freeDiameter.h */ 229 static void * routing_in_thr(void * arg) 230 { 231 TRACE_ENTRY("%p", arg); 232 233 /* Set the thread name */ 234 if (arg) { 235 char buf[48]; 236 snprintf(buf, sizeof(buf), "Routing-IN %p", arg); 237 fd_log_threadname ( buf ); 238 } else { 239 fd_log_threadname ( "Routing-IN" ); 240 } 241 242 /* Main thread loop */ 243 do { 244 struct msg * msg; 245 struct msg_hdr * hdr; 246 int is_req = 0; 247 int is_err = 0; 248 249 /* Test if we were told to stop */ 250 pthread_testcancel(); 251 252 /* Get the next message from the incoming queue */ 253 CHECK_FCT_DO( fd_fifo_get ( fd_g_incoming, &msg ), goto fatal_error ); 254 255 if (TRACE_BOOL(FULL)) { 256 TRACE_DEBUG(FULL, "Picked next message:"); 257 fd_msg_dump_one(FULL, msg); 258 } 259 260 /* Read the message header */ 261 CHECK_FCT_DO( fd_msg_hdr(msg, &hdr), goto fatal_error ); 262 is_req = hdr->msg_flags & CMD_FLAG_REQUEST; 263 is_err = hdr->msg_flags & CMD_FLAG_ERROR; 264 265 /* Handle incorrect bits */ 266 if (is_req && is_err) { 267 CHECK_FCT_DO( return_error( msg, "DIAMETER_INVALID_HDR_BITS"), goto fatal_error ); 268 continue; 269 } 270 271 272 273 274 275 276 } while (1); 277 278 fatal_error: 279 TRACE_DEBUG(INFO, "An error occurred in routing module! IN thread is terminating..."); 280 CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, 0, NULL), ); 281 return NULL; 282 } 283 38 284 /* Note: after testing if the message is to be handled locally, we should test for decorated NAI 39 285 (draft-ietf-dime-nai-routing-04 section 4.4) */ 286 40 287 /* Note2: if the message is still for local delivery, we should test for duplicate 41 288 (draft-asveren-dime-dupcons-00). This may conflict with path validation decisions, no clear answer yet */ 42 289 290 291 43 292 /* Initialize the routing module */ 44 293 int fd_rt_init(void) 45 294 { 295 TODO("Start the routing threads"); 46 296 return ENOTSUP; 47 297 } … … 50 300 int fd_rt_fini(void) 51 301 { 302 TODO("Stop the routing threads"); 52 303 return ENOTSUP; 53 304 } 54 305 55 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 ); 56 int fd_rt_fwd_unregister ( struct fd_rt_fwd_hdl * handler, void ** cbdata ); 57 58 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 ); 59 int fd_rt_out_unregister ( struct fd_rt_out_hdl * handler, void ** cbdata ); 306 307 -
include/freeDiameter/freeDiameter.h
r85 r86 286 286 287 287 /* 288 * FUNCTION: fd_peer_getbyid 289 * 290 * PARAMETERS: 291 * diamid : A \0 terminated string. 292 * peer : The peer is stored here if it exists. 293 * 294 * DESCRIPTION: 295 * Search a peer by its Diameter-Id. 296 * 297 * RETURN VALUE: 298 * 0 : *peer has been updated (to NULL if the peer is not found). 299 * !0 : An error occurred. 300 */ 301 int fd_peer_getbyid( char * diamid, struct peer_hdr ** peer ); 302 303 /* 288 304 * FUNCTION: peer_validate_register 289 305 * … … 481 497 enum fd_rt_fwd_dir { 482 498 RT_FWD_REQ = 1, /* The callback will be called on forwarded requests only */ 483 RT_FWD_A NS, /* The callback will be called on answers and errors only*/484 RT_FWD_A LL, /* The callback will be called on all forwarded messages*/499 RT_FWD_ALL = 2, /* The callback will be called on all forwarded messages (requests and answers )*/ 500 RT_FWD_ANS = 3 /* The callback will be called on answers and errors only */ 485 501 }; 486 502 … … 497 513 * DESCRIPTION: 498 514 * Register a new callback for forwarded messages. See explanations above. 515 * Note that there is no guaranteed order for the callbacks calls. 499 516 * 500 517 * RETURN VALUE:
Note: See TracChangeset
for help on using the changeset viewer.