p-cscf: Make sending requests configurable and disable it by default
[strongswan.git] / src / libcharon / plugins / p_cscf / p_cscf_handler.c
1 /*
2 * Copyright (C) 2016 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "p_cscf_handler.h"
17
18 #include <networking/host.h>
19 #include <utils/debug.h>
20
21 typedef struct private_p_cscf_handler_t private_p_cscf_handler_t;
22
23 /**
24 * Private data
25 */
26 struct private_p_cscf_handler_t {
27
28 /**
29 * Public interface
30 */
31 p_cscf_handler_t public;
32 };
33
34 METHOD(attribute_handler_t, handle, bool,
35 private_p_cscf_handler_t *this, ike_sa_t *ike_sa,
36 configuration_attribute_type_t type, chunk_t data)
37 {
38 host_t *server;
39 int family = AF_INET6;
40
41 switch (type)
42 {
43 case P_CSCF_IP4_ADDRESS:
44 family = AF_INET;
45 /* fall-through */
46 case P_CSCF_IP6_ADDRESS:
47 server = host_create_from_chunk(family, data, 0);
48 if (!server)
49 {
50 DBG1(DBG_CFG, "received invalid P-CSCF server IP");
51 return FALSE;
52 }
53 DBG1(DBG_CFG, "received P-CSCF server IP %H", server);
54 server->destroy(server);
55 return TRUE;
56 default:
57 return FALSE;
58 }
59 }
60
61 METHOD(attribute_handler_t, release, void,
62 private_p_cscf_handler_t *this, ike_sa_t *ike_sa,
63 configuration_attribute_type_t type, chunk_t data)
64 {
65 switch (type)
66 {
67 case P_CSCF_IP4_ADDRESS:
68 case P_CSCF_IP6_ADDRESS:
69 /* nothing to do as we only log the server IPs */
70 break;
71 default:
72 break;
73 }
74 }
75
76 /**
77 * Data for attribute enumerator
78 */
79 typedef struct {
80 enumerator_t public;
81 bool request_ipv4;
82 bool request_ipv6;
83 } attr_enumerator_t;
84
85 METHOD(enumerator_t, enumerate_attrs, bool,
86 attr_enumerator_t *this, configuration_attribute_type_t *type,
87 chunk_t *data)
88 {
89 if (this->request_ipv4)
90 {
91 *type = P_CSCF_IP4_ADDRESS;
92 *data = chunk_empty;
93 this->request_ipv4 = FALSE;
94 return TRUE;
95 }
96 if (this->request_ipv6)
97 {
98 *type = P_CSCF_IP6_ADDRESS;
99 *data = chunk_empty;
100 this->request_ipv6 = FALSE;
101 return TRUE;
102 }
103 return FALSE;
104 }
105
106 /**
107 * Check if the given host has a matching address family
108 */
109 static bool is_family(host_t *host, int *family)
110 {
111 return host->get_family(host) == *family;
112 }
113
114 /**
115 * Check if a list has a host of a given family
116 */
117 static bool has_host_family(linked_list_t *list, int family)
118 {
119 return list->find_first(list, (void*)is_family, NULL, &family) == SUCCESS;
120 }
121
122 METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
123 private_p_cscf_handler_t *this, ike_sa_t *ike_sa,
124 linked_list_t *vips)
125 {
126 attr_enumerator_t *enumerator;
127
128 if (ike_sa->get_version(ike_sa) == IKEV1)
129 {
130 return enumerator_create_empty();
131 }
132
133 INIT(enumerator,
134 .public = {
135 .enumerate = (void*)_enumerate_attrs,
136 .destroy = (void*)free,
137 },
138 );
139 if (lib->settings->get_bool(lib->settings, "%s.plugins.p-cscf.enable.%s",
140 FALSE, lib->ns, ike_sa->get_name(ike_sa)))
141 {
142 enumerator->request_ipv4 = has_host_family(vips, AF_INET);
143 enumerator->request_ipv6 = has_host_family(vips, AF_INET6);
144 }
145 return &enumerator->public;
146 }
147
148 METHOD(p_cscf_handler_t, destroy, void,
149 private_p_cscf_handler_t *this)
150 {
151 free(this);
152 }
153
154 /**
155 * See header
156 */
157 p_cscf_handler_t *p_cscf_handler_create()
158 {
159 private_p_cscf_handler_t *this;
160
161 INIT(this,
162 .public = {
163 .handler = {
164 .handle = _handle,
165 .release = _release,
166 .create_attribute_enumerator = _create_attribute_enumerator,
167 },
168 .destroy = _destroy,
169 },
170 );
171
172 return &this->public;
173 }