1 /** 2 * @file ucmp.c URI comparison 3 * 4 * Copyright (C) 2010 Creytiv.com 5 */ 6 #include <re_types.h> 7 #include <re_fmt.h> 8 #include <re_uri.h> 9 10 11 static int param_handler(const struct pl *pname, const struct pl *pvalue, 12 void *arg) 13 { 14 struct pl *other_params = arg; 15 struct pl other_pvalue = PL_INIT; 16 bool both; 17 18 if (0 == pl_strcmp(pname, "user")) 19 both = true; 20 else if (0 == pl_strcmp(pname, "ttl")) 21 both = true; 22 else if (0 == pl_strcmp(pname, "method")) 23 both = true; 24 else if (0 == pl_strcmp(pname, "maddr")) 25 both = true; 26 else if (0 == pl_strcmp(pname, "transport")) 27 both = true; 28 else 29 both = false; 30 31 if (uri_param_get(other_params, pname, &other_pvalue)) 32 return both ? ENOENT : 0; 33 34 return pl_casecmp(pvalue, &other_pvalue); 35 } 36 37 38 static int header_handler(const struct pl *hname, const struct pl *hvalue, 39 void *arg) 40 { 41 struct pl *other_headers = arg; 42 struct pl other_hvalue; 43 int err; 44 45 err = uri_header_get(other_headers, hname, &other_hvalue); 46 if (err) 47 return err; 48 49 return pl_casecmp(hvalue, &other_hvalue); 50 } 51 52 53 /** 54 * Compare two URIs - see RFC 3261 Section 19.1.4 55 * 56 * @param l Left-hand URI object 57 * @param r Right-hand URI object 58 * 59 * @return true if match, otherwise false 60 */ 61 bool uri_cmp(const struct uri *l, const struct uri *r) 62 { 63 int err; 64 65 if (!l || !r) 66 return false; 67 68 if (l == r) 69 return true; 70 71 /* A SIP and SIPS URI are never equivalent. */ 72 if (pl_casecmp(&l->scheme, &r->scheme)) 73 return false; 74 75 /* Comparison of the userinfo of SIP and SIPS URIs is case-sensitive */ 76 if (pl_cmp(&l->user, &r->user)) 77 return false; 78 79 if (pl_cmp(&l->password, &r->password)) 80 return false; 81 dummy_udp_recv_handler(const struct sa * src,struct mbuf * mb,void * arg)82 if (pl_casecmp(&l->host, &r->host)) 83 return false; 84 if (l->af != r->af) 85 return false; 86 87 if (l->port != r->port) 88 return false; 89 90 /* URI parameters */ helper_send_handler(int * err,struct sa * dst,struct mbuf * mb,void * arg)91 err = uri_params_apply(&l->params, param_handler, (void *)&r->params); 92 if (err) 93 return false; 94 err = uri_params_apply(&r->params, param_handler, (void *)&l->params); 95 if (err) 96 return false; 97 98 /* URI headers */ 99 err = uri_headers_apply(&l->headers, header_handler, 100 (void *)&r->headers); 101 if (err) helper_recv_handler(struct sa * src,struct mbuf * mb,void * arg)102 return false; 103 err = uri_headers_apply(&r->headers, header_handler, 104 (void *)&l->headers); 105 if (err) 106 return false; 107 108 /* Match */ 109 return true; 110 } 111