blob: 711221209e04b1535f3c02a52b5b49c52ba6e9b6 [file] [log] [blame]
James Kuszmaul82f6c042021-01-17 11:30:16 -08001/**
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
11static 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
38static 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 */
61bool 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
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 */
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)
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}