Changeset 1259:82280e745a89 in freeDiameter for extensions/rt_redirect/redir_fwd.c
- Timestamp:
- Mar 24, 2014, 9:13:38 PM (10 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
extensions/rt_redirect/redir_fwd.c
r1127 r1259 59 59 int nbrh = 0; 60 60 struct redir_entry * entry; 61 61 62 62 TRACE_ENTRY("%p %p", cbdata, msg); 63 63 64 64 CHECK_PARAMS(msg && *msg); 65 65 66 66 m = *msg; 67 67 68 68 /* First get the header */ 69 69 CHECK_FCT( fd_msg_hdr(m, &hdr) ); 70 70 71 71 /* Check if we have an error */ 72 72 ASSERT(!(hdr->msg_flags & CMD_FLAG_REQUEST)); … … 75 75 return 0; 76 76 } 77 77 78 78 /* Now get the AVPs we are interested in */ 79 79 CHECK_FCT( fd_msg_browse(m, MSG_BRW_FIRST_CHILD, &avp, NULL) ); 80 80 while (avp) { 81 81 struct avp_hdr * ahdr; 82 82 83 83 CHECK_FCT( fd_msg_avp_hdr( avp, &ahdr ) ); 84 84 if (! (ahdr->avp_flags & AVP_FLAG_VENDOR)) { … … 90 90 a_oh = ahdr->avp_value; 91 91 break; 92 92 93 93 case AC_RESULT_CODE: 94 94 /* Parse this AVP */ … … 96 96 ASSERT( ahdr->avp_value ); 97 97 a_rc = ahdr->avp_value; 98 98 99 99 if (a_rc->u32 != ER_DIAMETER_REDIRECT_INDICATION) { 100 100 /* It is not a REDIRECT error, we don't do anything */ … … 102 102 } 103 103 break; 104 104 105 105 case AC_REDIRECT_HOST: 106 106 { … … 112 112 int l4 = 0; 113 113 char proto = 0; 114 114 115 115 /* Parse this AVP */ 116 116 CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, NULL ) ); 117 117 ASSERT( ahdr->avp_value ); 118 118 119 119 nbrh++; 120 121 CHECK_FCT_DO( fd_os_parse_DiameterURI(ahdr->avp_value->os.data, ahdr->avp_value->os.len, 120 121 CHECK_FCT_DO( fd_os_parse_DiameterURI(ahdr->avp_value->os.data, ahdr->avp_value->os.len, 122 122 &id, &len, &secure, &port, &l4, &proto), 123 123 { … … 125 125 break; 126 126 } ); 127 127 128 128 /* Now check if the transport & protocol are supported */ 129 129 if (proto && (proto != 'd')) { … … 137 137 break; 138 138 } 139 139 140 140 /* It looks OK, save this entry. */ 141 141 142 142 CHECK_MALLOC( h = malloc(sizeof(struct redir_host)) ); 143 143 memset(h, 0, sizeof(struct redir_host)); … … 146 146 h->len = len; 147 147 /* later: secure, port */ 148 148 149 149 /* The list is kept ordered by id so that it is faster to compare to candidates later */ 150 150 for (li = task.rh.next; li != &task.rh; li = li->next) { … … 183 183 CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) ); 184 184 } 185 185 186 186 /* Check we have received the necessary information */ 187 187 if (!a_rc) { … … 189 189 goto out; 190 190 } 191 191 192 192 if (!a_oh) { 193 193 TRACE_DEBUG(FULL, "Invalid Diameter answer without an Origin-Host AVP, Redirect module gave up"); 194 194 goto out; 195 195 } 196 196 197 197 if (FD_IS_LIST_EMPTY(&task.rh)) { 198 198 TRACE_DEBUG(FULL, "Diameter answer with a DIAMETER_REDIRECT_INDICATION Result-Code AVP but no valid/supported Redirect-Host AVP, Redirect module gave up"); … … 204 204 goto out; 205 205 } 206 206 207 207 /* It looks like we can process the Redirect indication */ 208 208 209 209 /* Search for the peers we already know */ 210 210 for (li = task.rh.next; li != &task.rh; li = li->next) { 211 211 struct redir_host * h = li->o; 212 212 struct peer_hdr * peer; 213 213 214 214 CHECK_FCT( fd_peer_getbyid( h->id, h->len, 1, &peer ) ); 215 215 if (peer) { … … 221 221 } 222 222 } 223 223 224 224 TRACE_DEBUG(FULL, "Redirect module: received %d Redirect-Hosts, %d are known peers, %d have an OPEN connection", nbrh, known, actives); 225 225 226 226 /* in this version, we only redirect when there are known active peers. TODO: add new peers via fd_peer_add when no active peer is available */ 227 227 228 228 if (!actives) { 229 229 TRACE_DEBUG(INFO, "Unable to comply to Redirect indication: none of the peers included is in OPEN state"); 230 230 goto out; 231 231 } 232 232 233 233 /* From this point, we will re-send the query to a different peer, so stop forwarding the answer here */ 234 234 *msg = NULL; 235 235 236 236 /* Get the query's routing data & add the new error */ 237 237 CHECK_FCT( fd_msg_answ_getq(m, &q) ); … … 239 239 CHECK_FCT( fd_msg_source_get( m, &nh, &nhlen ) ); 240 240 CHECK_FCT( fd_rtd_error_add(rtd, nh, nhlen, a_oh->os.data, a_oh->os.len, a_rc->u32, NULL, NULL) ); 241 241 242 242 /* Create a redir_rule */ 243 243 CHECK_FCT( redir_entry_new(&entry, &task.rh, task.rhu, q, nh, nhlen, a_oh->os.data, a_oh->os.len) ); 244 244 245 245 CHECK_POSIX( pthread_mutex_lock(&redir_exp_peer_lock) ); 246 246 /* Insert in the split list */ … … 253 253 CHECK_FCT( fd_msg_answ_detach(m) ); 254 254 CHECK_FCT( fd_msg_free(m) ); 255 255 256 256 /* Send it */ 257 257 CHECK_FCT( fd_msg_send(&q, NULL, NULL) ); 258 258 259 259 /* Done! */ 260 260 261 261 out: 262 262 while (!FD_IS_LIST_EMPTY(&task.rh)) { … … 266 266 free(h); 267 267 } 268 268 269 269 return 0; 270 270
Note: See TracChangeset
for help on using the changeset viewer.