Changeset 738:d666051658bd in freeDiameter
- Timestamp:
- Mar 2, 2011, 6:21:59 PM (13 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
extensions/app_radgw/rgw_clients.c
r718 r738 732 732 733 733 /* first, check if the nas_id is the fqdn of the peer or a known alias */ 734 if (!fd_os_almostcase cmp(nas_id + 1, nas_id_len,735 cli->fqdn, cli->fqdn_len )) {734 if (!fd_os_almostcasesrch(nas_id + 1, nas_id_len, 735 cli->fqdn, cli->fqdn_len, NULL)) { 736 736 TRACE_DEBUG(FULL, "NAS-Identifier contains the fqdn of the client"); 737 737 found = 1; -
extensions/app_redirect/ard_rules.c
r723 r738 94 94 95 95 if (c->is_regex == 0) { 96 if ( ! fd_os_almostcase cmp(c->s, c->sl, s, l) )96 if ( ! fd_os_almostcasesrch(c->s, c->sl, s, l, NULL) ) 97 97 *match = 1; 98 98 } else { -
extensions/rt_redirect/redir_fwd.c
r717 r738 150 150 for (li = task.rh.next; li != &task.rh; li = li->next) { 151 151 struct redir_host * nhost = li->o; 152 if ( fd_os_ almostcasecmp(id, len, nhost->id, nhost->len) <= 0 )152 if ( fd_os_cmp(id, len, nhost->id, nhost->len) <= 0 ) 153 153 break; 154 154 } -
extensions/rt_redirect/redir_out.c
r717 r738 171 171 /* Special case: ALL_HOST rules: we decrease the score of the Origin-Host if present */ 172 172 if (e->type == ALL_HOST) { 173 cmp = fd_os_almostcase cmp(cand->diamid, cand->diamidlen, e->data.host.s, e->data.host.l);173 cmp = fd_os_almostcasesrch(cand->diamid, cand->diamidlen, e->data.host.s, e->data.host.l, NULL); 174 174 if (!cmp) { 175 175 TRACE_DEBUG(FULL, "Redirect msg %p: peer '%.*s' += %d (previous ALL_HOST Redirect originated from this peer)", msg, cand->diamidlen, cand->diamid, FD_SCORE_SENT_REDIRECT); … … 198 198 struct rtd_candidate * cand = (struct rtd_candidate *) lic; 199 199 200 /* Is this candidate in the "Redirect-Host" list ? */200 /* Is this candidate in the "Redirect-Host" list ? We must search caseinsentive here. */ 201 201 for (lirh = e->target_peers_list.next; lirh != &e->target_peers_list; lirh = lirh->next) { 202 202 struct redir_host * host = lirh->o; 203 204 cmp = fd_os_cmp( cand->diamid, cand->diamidlen, host->id, host->len ); 205 206 if (cmp < 0) 207 break; /* targets are ordered */ 203 int cont; 204 205 cmp = fd_os_almostcasesrch( cand->diamid, cand->diamidlen, host->id, host->len, &cont ); 208 206 209 207 if (cmp == 0) { 210 208 TRACE_DEBUG(FULL, "Redirect msg %p: peer '%.*s' += %d (rule t:%d @%p)", msg, cand->diamidlen, cand->diamid, redirects_usages[e->type].score, e->type, e); 211 209 cand->score += redirects_usages[e->type].score; 212 } 210 break; 211 } 212 if (!cont) 213 break; 213 214 } 214 215 } -
include/freeDiameter/libfdproto.h
r736 r738 621 621 622 622 /* A roughly case-insensitive variant, which actually only compares ASCII chars (0-127) in a case-insentitive maneer 623 -- this should be OK with (old) DNS names. Not sure how it works with IDN... 624 -- it also clearly does not support locales where a lowercase letter uses more space than upper case, such as ß -> ss 625 It is slower than fd_os_cmp... 626 This function should give the same order as fd_os_cmp, except when it finds 2 strings to be equal. 623 -- it does not support locales where a lowercase letter uses more space than upper case, such as ß -> ss 624 It is slower than fd_os_cmp. 627 625 Note that the result is NOT the same as strcasecmp !!! 628 */ 629 int fd_os_almostcasecmp_int(uint8_t * os1, size_t os1sz, uint8_t * os2, size_t os2sz); 630 #define fd_os_almostcasecmp(_o1, _l1, _o2, _l2) fd_os_almostcasecmp_int((os0_t)(_o1), _l1, (os0_t)(_o2), _l2) 626 627 This function gives the same order as fd_os_cmp, except when it finds 2 strings to be equal. 628 However this is not always sufficient: 629 for example fd_os_cmp gives: "Ac" < "aB" < "aa" 630 if you attempt to fd_os_almostcasesrch "Aa" you will actually have to go past "aB" which is > "Aa". 631 Therefore you can use the maybefurther parameter. 632 This parameter is 1 on return if os1 may have been stored further that os2 (assuming os2 values are ordered by fd_os_cmp) 633 and 0 if we are sure that it is not the case. 634 When looping through a list of fd_os_cmp classified values, this parameter must be used to stop looping, in addition to the comp result. 635 */ 636 int fd_os_almostcasesrch_int(uint8_t * os1, size_t os1sz, uint8_t * os2, size_t os2sz, int * maybefurther); 637 #define fd_os_almostcasesrch(_o1, _l1, _o2, _l2, _mb) fd_os_almostcasesrch_int((os0_t)(_o1), _l1, (os0_t)(_o2), _l2, _mb) 631 638 632 639 /* Analyze a DiameterURI and return its components. -
libfdcore/p_ce.c
r725 r738 304 304 305 305 /* We check that the value matches what we know, otherwise disconnect the peer */ 306 if (fd_os_almostcase cmp(hdr->avp_value->os.data, hdr->avp_value->os.len,307 peer->p_hdr.info.pi_diamid, peer->p_hdr.info.pi_diamidlen )) {306 if (fd_os_almostcasesrch(hdr->avp_value->os.data, hdr->avp_value->os.len, 307 peer->p_hdr.info.pi_diamid, peer->p_hdr.info.pi_diamidlen, NULL)) { 308 308 TRACE_DEBUG(INFO, "Received a message with Origin-Host set to '%.*s' while expecting '%s'\n", 309 309 hdr->avp_value->os.len, hdr->avp_value->os.data, peer->p_hdr.info.pi_diamid); … … 813 813 if (peer->p_hdr.info.config.pic_realm) { 814 814 size_t len = strlen(peer->p_hdr.info.config.pic_realm); 815 if (fd_os_almostcase cmp(peer->p_hdr.info.config.pic_realm, len, peer->p_hdr.info.runtime.pir_realm, peer->p_hdr.info.runtime.pir_realmlen)) {815 if (fd_os_almostcasesrch(peer->p_hdr.info.config.pic_realm, len, peer->p_hdr.info.runtime.pir_realm, peer->p_hdr.info.runtime.pir_realmlen, NULL)) { 816 816 TRACE_DEBUG(INFO, "Rejected CER from peer '%s', realm mismatch with configured value (returning DIAMETER_UNKNOWN_PEER).\n", peer->p_hdr.info.pi_diamid); 817 817 pei.pei_errcode = "DIAMETER_UNKNOWN_PEER"; /* maybe AVP_NOT_ALLOWED would be better fit? */ -
libfdcore/peers.c
r725 r738 94 94 { 95 95 struct fd_peer *p = NULL; 96 struct fd_list * li ;96 struct fd_list * li, *li_inf; 97 97 int ret = 0; 98 98 … … 143 143 /* Ok, now check if we don't already have an entry with the same Diameter Id, and insert this one */ 144 144 CHECK_POSIX( pthread_rwlock_wrlock(&fd_g_peers_rw) ); 145 145 li_inf = &fd_g_peers; 146 146 for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { 147 147 struct fd_peer * next = (struct fd_peer *)li; 148 int cmp = fd_os_almostcasecmp( p->p_hdr.info.pi_diamid, p->p_hdr.info.pi_diamidlen, 149 next->p_hdr.info.pi_diamid, next->p_hdr.info.pi_diamidlen ); 150 if (cmp > 0) 151 continue; 152 if (cmp == 0) 148 int cont; 149 int cmp = fd_os_almostcasesrch( p->p_hdr.info.pi_diamid, p->p_hdr.info.pi_diamidlen, 150 next->p_hdr.info.pi_diamid, next->p_hdr.info.pi_diamidlen, 151 &cont ); 152 if (cmp < 0) 153 li_inf = li; 154 155 if (cmp == 0) { 153 156 ret = EEXIST; 154 break; 157 break; 158 } 159 if (!cont) 160 break; 155 161 } 156 162 … … 162 168 163 169 /* Insert the new element in the list */ 164 fd_list_insert_ before( li, &p->p_hdr.chain );170 fd_list_insert_after( li_inf, &p->p_hdr.chain ); 165 171 } while (0); 166 172 … … 185 191 /* Search in the list */ 186 192 CHECK_POSIX( pthread_rwlock_rdlock(&fd_g_peers_rw) ); 187 for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { 188 struct fd_peer * next = (struct fd_peer *)li; 189 int cmp; 190 if (igncase) 191 cmp = fd_os_almostcasecmp( diamid, diamidlen, next->p_hdr.info.pi_diamid, next->p_hdr.info.pi_diamidlen ); 192 else 193 cmp = fd_os_cmp( diamid, diamidlen, next->p_hdr.info.pi_diamid, next->p_hdr.info.pi_diamidlen ); 194 if (cmp > 0) 195 continue; 196 if (cmp == 0) 197 *peer = &next->p_hdr; 198 break; 199 } 193 if (igncase) 194 for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { 195 struct fd_peer * next = (struct fd_peer *)li; 196 int cmp, cont; 197 cmp = fd_os_almostcasesrch( diamid, diamidlen, next->p_hdr.info.pi_diamid, next->p_hdr.info.pi_diamidlen, &cont ); 198 if (cmp == 0) { 199 *peer = &next->p_hdr; 200 break; 201 } 202 if (!cont) 203 break; 204 } 205 else 206 for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { 207 struct fd_peer * next = (struct fd_peer *)li; 208 int cmp = fd_os_cmp( diamid, diamidlen, next->p_hdr.info.pi_diamid, next->p_hdr.info.pi_diamidlen ); 209 if (cmp > 0) 210 continue; 211 if (cmp == 0) 212 *peer = &next->p_hdr; 213 break; 214 } 200 215 CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) ); 201 216 … … 429 444 struct avp *avp_oh; 430 445 struct avp_hdr * avp_hdr; 431 struct fd_list * li ;446 struct fd_list * li, *li_inf; 432 447 int found = 0; 433 448 int ret = 0; … … 470 485 CHECK_POSIX( pthread_rwlock_wrlock(&fd_g_peers_rw) ); 471 486 487 li_inf = &fd_g_peers; 472 488 for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { 473 int cmp ;489 int cmp, cont; 474 490 peer = (struct fd_peer *)li->o; 475 cmp = fd_os_almostcasecmp( avp_hdr->avp_value->os.data, avp_hdr->avp_value->os.len, peer->p_hdr.info.pi_diamid, peer->p_hdr.info.pi_diamidlen ); 476 if (cmp > 0) 491 cmp = fd_os_almostcasesrch( avp_hdr->avp_value->os.data, avp_hdr->avp_value->os.len, peer->p_hdr.info.pi_diamid, peer->p_hdr.info.pi_diamidlen, &cont ); 492 if (cmp < 0) { 493 li_inf = li; 477 494 continue; 478 if (cmp == 0) 495 } 496 if (cmp == 0) { 479 497 found = 1; 480 break; 498 break; 499 } 500 if (!cont) 501 break; 481 502 } 482 503 … … 500 521 501 522 /* Insert the new peer in the list (the PSM will take care of setting the expiry after validation) */ 502 fd_list_insert_ before( li, &peer->p_hdr.chain );523 fd_list_insert_after( li_inf, &peer->p_hdr.chain ); 503 524 504 525 /* Start the PSM, which will receive the event bellow */ -
libfdcore/routing_dispatch.c
r717 r738 274 274 275 275 /* In the AVPs, the value comes from the network, so let's be case permissive */ 276 if (dh && !fd_os_almostcase cmp(dh->os.data, dh->os.len, c->diamid, c->diamidlen) ) {276 if (dh && !fd_os_almostcasesrch(dh->os.data, dh->os.len, c->diamid, c->diamidlen, NULL) ) { 277 277 /* The candidate is the Destination-Host */ 278 278 c->score += FD_SCORE_FINALDEST; 279 279 } else { 280 if (dr && !fd_os_almostcase cmp(dr->os.data, dr->os.len, c->realm, c->realmlen) ) {280 if (dr && !fd_os_almostcasesrch(dr->os.data, dr->os.len, c->realm, c->realmlen, NULL) ) { 281 281 /* The candidate's realm matchs the Destination-Realm */ 282 282 c->score += FD_SCORE_REALM; … … 592 592 ASSERT( ahdr->avp_value ); 593 593 /* Compare the Destination-Host AVP of the message with our identity */ 594 if (!fd_os_almostcase cmp(ahdr->avp_value->os.data, ahdr->avp_value->os.len, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len)) {594 if (!fd_os_almostcasesrch(ahdr->avp_value->os.data, ahdr->avp_value->os.len, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, NULL)) { 595 595 is_dest_host = YES; 596 596 } else { … … 613 613 dr_val = ahdr->avp_value; 614 614 /* Compare the Destination-Realm AVP of the message with our identity */ 615 if (!fd_os_almostcase cmp(dr_val->os.data, dr_val->os.len, fd_g_config->cnf_diamrlm, fd_g_config->cnf_diamrlm_len)) {615 if (!fd_os_almostcasesrch(dr_val->os.data, dr_val->os.len, fd_g_config->cnf_diamrlm, fd_g_config->cnf_diamrlm_len, NULL)) { 616 616 is_dest_realm = YES; 617 617 } else { -
libfdproto/ostr.c
r730 r738 69 69 } 70 70 71 /* a littleless sensitive to case, slower. */72 int fd_os_almostcase cmp_int(uint8_t * os1, size_t os1sz, uint8_t * os2, size_t os2sz)71 /* less sensitive to case, slower. */ 72 int fd_os_almostcasesrch_int(uint8_t * os1, size_t os1sz, uint8_t * os2, size_t os2sz, int *maybefurther) 73 73 { 74 74 int i; 75 int res = 0; 76 75 77 ASSERT( os1 && os2); 78 if (maybefurther) 79 *maybefurther = 0; 80 76 81 if (os1sz < os2sz) 77 82 return -1; 83 84 if (maybefurther) 85 *maybefurther = 1; 86 78 87 if (os1sz > os2sz) 79 88 return 1; … … 83 92 continue; 84 93 94 if (!res) 95 res = os1[i] < os2[i] ? -1 : 1; 96 85 97 if (asciitolower(os1[i]) == asciitolower(os2[i])) 86 98 continue; 87 99 88 return os1[i] < os2[i] ? -1 : 1;100 return res; 89 101 } 90 102 -
libfdproto/rt_data.c
r717 r738 160 160 for (li = rtd->candidates.next; li != &rtd->candidates; li = li->next) { 161 161 struct rtd_candidate * c = (struct rtd_candidate *) li; 162 163 int cmp = fd_os_almostcase cmp(id, idsz, c->diamid, c->diamidlen);162 int cont; 163 int cmp = fd_os_almostcasesrch(id, idsz, c->diamid, c->diamidlen, &cont); 164 164 165 165 if (!cmp) { … … 172 172 } 173 173 174 if (c mp > 0)174 if (cont) 175 175 continue; 176 176 -
tests/testostr.c
r717 r738 99 99 CHECK( 0, strcasecmp(res, TEST_IDN_UTF8) ); 100 100 CHECK( 0, fd_os_cmp(res, len, TEST_IDN_UTF8, CONSTSTRLEN(TEST_IDN_UTF8)) ); 101 CHECK( 0, fd_os_almostcase cmp(res, len, TEST_IDN_UTF8, CONSTSTRLEN(TEST_IDN_UTF8)) );101 CHECK( 0, fd_os_almostcasesrch(res, len, TEST_IDN_UTF8, CONSTSTRLEN(TEST_IDN_UTF8), NULL) ); 102 102 CHECK( 0, fd_os_validate_DiameterIdentity(&res, &len, 0) ); 103 103 CHECK( 0, strcasecmp(res, TEST_IDN_UTF8) ); … … 128 128 } 129 129 130 { 131 /* test fd_os_cmp and fd_os_almostcasesrch and that they are compatible */ 132 char *t1 = "a"; 133 char *t2 = "b"; 134 char *t3 = "C"; 135 char *t4 = "d"; 136 char *t5 = "aa"; 137 char *t6 = "aB"; 138 char *t7 = "Ac"; 139 char *t8 = "aD"; 140 char *t9 = "AAA"; 141 142 char *t5b = "Aa"; 143 char *t6b = "ab"; 144 145 /* First, create a list with all the elements in order given by fd_os_cmp */ 146 char *t[] = { t1, t2, t3, t4, t5, t6,t7, t8, t9 }; 147 int i; 148 struct fd_list *li, l = FD_LIST_INITIALIZER(l); 149 for (i = 0; i < sizeof(t) / sizeof(t[0]); i++) { 150 /* insert t[i] */ 151 struct fd_list *n = malloc(sizeof(struct fd_list)); 152 CHECK( 1, n ? 1 : 0 ); 153 fd_list_init(n, t[i]); 154 for (li = l.next; li != &l; li = li->next) { 155 if ( fd_os_cmp(t[i], strlen(t[i]), li->o, strlen(li->o)) < 0 ) 156 break; 157 } 158 fd_list_insert_before(li, n); 159 } 160 /* in principle the result is: [ "C", "a", "b", "d", "Ac", "aB", "aD", "aa", "AAA" ] */ 161 162 /* Since there is no equal value in the list (even case-insensitive), check that the order is valid also for the caseinsensitive variant */ 163 for (li = l.next; li != l.prev; li = li->next) { 164 CHECK( 1, fd_os_almostcasesrch(li->o, strlen(li->o), li->next->o, strlen(li->next->o), NULL) < 0 ? 1 : 0 ); 165 } 166 167 /* Now check that we can case-insentively find t5b and t6b to be equal to t5 and t6 resp. (this is how we use it in the daemon) */ 168 for (li = l.next; li != &l; li = li->next) { 169 int cont, cmp; 170 cmp = fd_os_almostcasesrch(t5b, strlen(t5b), li->o, strlen(li->o), &cont); 171 TRACE_DEBUG(FULL, "Comp '%s' : %d, %d", (char *)li->o, cmp, cont); 172 if (cmp == 0) 173 break; 174 if (!cont) 175 break; 176 } 177 CHECK( li->o, t5 ); 178 179 for (li = l.next; li != &l; li = li->next) { 180 int cont, cmp; 181 cmp = fd_os_almostcasesrch(t6b, strlen(t6b), li->o, strlen(li->o), &cont); 182 TRACE_DEBUG(FULL, "Comp '%s' : %d, %d", (char *)li->o, cmp, cont); 183 if (cmp == 0) 184 break; 185 if (!cont) 186 break; 187 } 188 CHECK( li->o, t6 ); 189 190 191 /* done */ 192 while (!FD_IS_LIST_EMPTY(&l)) { 193 li = l.next; 194 fd_list_unlink(li); 195 free(li); 196 } 197 } 198 130 199 /* That's all for the tests yet */ 131 200 PASSTEST();
Note: See TracChangeset
for help on using the changeset viewer.