Changeset 706:4ffbc9f1e922 in freeDiameter for libfdproto/rt_data.c
- Timestamp:
- Feb 9, 2011, 3:26:58 PM (13 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libfdproto/rt_data.c
r662 r706 50 50 /* Items of the errors list */ 51 51 struct rtd_error { 52 struct fd_list chain; /* link in the list, ordered by nexthop */ 53 char * nexthop;/* the peer the message was sent to */ 54 char * erh; /* the origin of the error */ 52 struct fd_list chain; /* link in the list, ordered by nexthop (fd_os_cmp) */ 53 DiamId_t nexthop;/* the peer the message was sent to */ 54 size_t nexthoplen; /* cached string length */ 55 DiamId_t erh; /* the origin of the error */ 56 size_t erhlen; /* cached string length */ 55 57 uint32_t code; /* the error code */ 56 58 }; … … 107 109 } 108 110 109 /* Add a peer to the candidates list */110 int fd_rtd_candidate_add(struct rt_data * rtd, char * peerid, char * realm)111 /* Add a peer to the candidates list. The source is our local peer list, so no need to care for the case here. */ 112 int fd_rtd_candidate_add(struct rt_data * rtd, DiamId_t peerid, size_t peeridlen, DiamId_t realm, size_t realmlen) 111 113 { 112 114 struct fd_list * prev; 113 115 struct rtd_candidate * new; 114 116 115 TRACE_ENTRY("%p %p ", rtd, peerid);116 CHECK_PARAMS(rtd && peerid );117 TRACE_ENTRY("%p %p %zd %p %zd", rtd, peerid, peeridlen, realm, realmlen); 118 CHECK_PARAMS(rtd && peerid && peeridlen); 117 119 118 120 /* Since the peers are ordered when they are added (fd_g_activ_peers) we search for the position from the end -- this should be efficient */ 119 121 for (prev = rtd->candidates.prev; prev != &rtd->candidates; prev = prev->prev) { 120 122 struct rtd_candidate * cp = (struct rtd_candidate *) prev; 121 int cmp = strcmp(peerid, cp->diamid);123 int cmp = fd_os_cmp(peerid, peeridlen, cp->diamid, cp->diamidlen); 122 124 if (cmp > 0) 123 125 break; … … 127 129 } 128 130 131 /* Create the new entry */ 129 132 CHECK_MALLOC( new = malloc(sizeof(struct rtd_candidate)) ); 130 133 memset(new, 0, sizeof(struct rtd_candidate) ); 131 134 fd_list_init(&new->chain, NULL); 132 CHECK_MALLOC( new->diamid = strdup(peerid) ); 133 CHECK_MALLOC( new->realm = strdup(realm) ); 134 135 CHECK_MALLOC( new->diamid = os0dup(peerid, peeridlen) ) 136 new->diamidlen = peeridlen; 137 if (realm) { 138 CHECK_MALLOC( new->realm = os0dup(realm, realmlen) ) 139 new->realmlen = realmlen; 140 } 141 142 /* insert in the list at the correct position */ 135 143 fd_list_insert_after(prev, &new->chain); 136 144 … … 138 146 } 139 147 140 /* Remove a peer from the candidates (if it is found) */141 void fd_rtd_candidate_del(struct rt_data * rtd, char * peerid, size_t sz /* if !0, peerid does not need to be \0 terminated */)148 /* Remove a peer from the candidates (if it is found). Case insensitive search since the names are received from other peers */ 149 void fd_rtd_candidate_del(struct rt_data * rtd, uint8_t * id, size_t idsz) 142 150 { 143 151 struct fd_list * li; 144 152 145 TRACE_ENTRY("%p %p %zd", rtd, peerid, sz); 146 CHECK_PARAMS_DO( rtd && peerid , return ); 153 TRACE_ENTRY("%p %p %zd", rtd, id, idsz); 154 CHECK_PARAMS_DO( rtd && id && idsz, return ); 155 156 if (!fd_os_is_valid_DiameterIdentity(id, idsz)) 157 /* it cannot be in the list */ 158 return; 147 159 148 160 for (li = rtd->candidates.next; li != &rtd->candidates; li = li->next) { 149 161 struct rtd_candidate * c = (struct rtd_candidate *) li; 150 int cmp; 151 if (sz) { 152 cmp = strncmp(peerid, c->diamid, sz); 153 if (!cmp) { 154 int len = strlen(c->diamid); 155 if (sz < len) 156 cmp = -1; 157 else if (sz == len) 158 cmp = 0; 159 else cmp = 1; 160 } 161 } else { 162 cmp = strcmp(peerid, c->diamid); 163 } 162 163 int cmp = fd_os_almostcasecmp(id, idsz, c->diamid, c->diamidlen); 164 164 165 165 if (!cmp) { … … 175 175 continue; 176 176 177 /* The list is ordered only if not extracted */177 /* The list is guaranteed to be ordered only if not extracted */ 178 178 if (! rtd->extracted) 179 179 break; … … 183 183 } 184 184 185 /* If a peer returned a protocol error for this message, save it so that we don't try to send it there again */ 186 int fd_rtd_error_add(struct rt_data * rtd, char * sentto, uint8_t * origin, size_t originsz, uint32_t rcode) 185 /* If a peer returned a protocol error for this message, save it so that we don't try to send it there again. 186 Case insensitive search since the names are received from other peers*/ 187 int fd_rtd_error_add(struct rt_data * rtd, DiamId_t sentto, size_t senttolen, uint8_t * origin, size_t originsz, uint32_t rcode) 187 188 { 188 189 struct fd_list * li; 189 190 int match = 0; 190 191 191 TRACE_ENTRY("%p %p % p %d", rtd, sentto, origin, rcode);192 CHECK_PARAMS( rtd && sentto ); /* origin may be NULL */192 TRACE_ENTRY("%p %p %zd %p %zd %u", rtd, sentto, senttolen, origin, originsz, rcode); 193 CHECK_PARAMS( rtd && sentto && senttolen ); /* origin may be NULL */ 193 194 194 195 /* First add the new error entry */ 195 196 for (li = rtd->errors.next; li != &rtd->errors; li = li->next) { 196 197 struct rtd_error * e = (struct rtd_error *) li; 197 int cmp = strcmp(sentto, e->nexthop);198 int cmp = fd_os_cmp(sentto, senttolen, e->nexthop, e->nexthoplen); 198 199 if (cmp > 0) 199 200 continue; … … 203 204 } 204 205 205 /* If we already had this entry, we should not have sent the message again to this peer... anyway... */ 206 /* If we already had this entry, we should not have sent the message again to this peer... anyway, let's close our eyes. */ 207 /* in the normal case, we save the error */ 206 208 if (!match) { 207 209 /* Add a new entry in the error list */ … … 210 212 memset(new, 0, sizeof(struct rtd_error)); 211 213 fd_list_init(&new->chain, NULL); 212 CHECK_MALLOC(new->nexthop = strdup(sentto)); 214 215 CHECK_MALLOC(new->nexthop = os0dup(sentto, senttolen)); 216 new->nexthoplen = senttolen; 217 213 218 if (origin) { 214 CHECK_MALLOC( new->erh = malloc(originsz + 1) ); 215 memcpy(new->erh, origin, originsz); 216 new->erh[originsz] = '\0'; 219 if (!originsz) { 220 originsz=strlen((char *)origin); 221 } else { 222 if (!fd_os_is_valid_DiameterIdentity(origin, originsz)){ 223 TRACE_DEBUG(FULL, "Received error %d from peer with invalid Origin-Host AVP, not saved", rcode); 224 origin = NULL; 225 goto after_origin; 226 } 227 } 228 CHECK_MALLOC( new->erh = (DiamId_t)os0dup(origin, originsz) ); 229 new->erhlen = originsz; 217 230 } 231 after_origin: 218 232 new->code = rcode; 219 233 fd_list_insert_before(li, &new->chain); … … 221 235 222 236 /* Finally, remove this (these) peers from the candidate list */ 223 fd_rtd_candidate_del(rtd, sentto, 0);237 fd_rtd_candidate_del(rtd, (os0_t)sentto, senttolen); 224 238 if (origin) 225 fd_rtd_candidate_del(rtd, (char *)origin, originsz);239 fd_rtd_candidate_del(rtd, origin, originsz); 226 240 227 241 /* Done! */ … … 274 288 fd_list_move_end(candidates, &highest); 275 289 276 /* And the new high score is this reset */290 /* And the new high score is set */ 277 291 hs = c->score; 278 292 }
Note: See TracChangeset
for help on using the changeset viewer.