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