1 /*
2 * usrloc_db.c
3 *
4 * Created on: Nov 11, 2013
5 * Author: carlos
6 *
7 * Copyright (C) 2019 Aleksandar Yosifov
8 */
9
10 #include "../../lib/srdb1/db.h"
11 #include "usrloc.h"
12 #include "usrloc_db.h"
13
14 str id_col = str_init(ID_COL);
15 str domain_col = str_init(DOMAIN_COL);
16 str aor_col = str_init(AOR_COL);
17 str host_col = str_init(HOST_COL);
18 str port_col = str_init(PORT_COL);
19 str protocol_col = str_init(PROTOCOL_COL);
20 str received_col = str_init(RECEIVED_COL);
21 str received_port_col = str_init(RECEIVED_PORT_COL);
22 str received_proto_col = str_init(RECEIVED_PROTO_COL);
23 str path_col = str_init(PATH_COL);
24 str rinstance_col = str_init(RINSTANCE_COL);
25 str rx_session_id_col = str_init(RX_SESSION_ID_COL);
26 str reg_state_col = str_init(REG_STATE_COL);
27 str expires_col = str_init(EXPIRES_COL);
28 str service_routes_col = str_init(SERVICE_ROUTES_COL);
29 str socket_col = str_init(SOCKET_COL);
30 str public_ids_col = str_init(PUBLIC_IDS_COL);
31 str security_type_col = str_init(SECURITY_TYPE_COL);
32 str mode_col = str_init(MODE_COL);
33 str ck_col = str_init(CK_COL);
34 str ik_col = str_init(IK_COL);
35 str ealg_col = str_init(EALG_COL);
36 str ialg_col = str_init(IALG_COL);
37 str port_pc_col = str_init(PORTPC_COL);
38 str port_ps_col = str_init(PORTPS_COL);
39 str port_uc_col = str_init(PORTUC_COL);
40 str port_us_col = str_init(PORTUS_COL);
41 str spi_pc_col = str_init(SPIPC_COL);
42 str spi_ps_col = str_init(SPIPS_COL);
43 str spi_uc_col = str_init(SPIUC_COL);
44 str spi_us_col = str_init(SPIUS_COL);
45 str t_security_type_col = str_init(T_SECURITY_TYPE_COL);
46 str t_protocol_col = str_init(T_PROTOCOL_COL);
47 str t_mode_col = str_init(T_MODE_COL);
48 str t_ck_col = str_init(T_CK_COL);
49 str t_ik_col = str_init(T_IK_COL);
50 str t_ealg_col = str_init(T_EALG_COL);
51 str t_ialg_col = str_init(T_IALG_COL);
52 str t_port_pc_col = str_init(T_PORTPC_COL);
53 str t_port_ps_col = str_init(T_PORTPS_COL);
54 str t_port_uc_col = str_init(T_PORTUC_COL);
55 str t_port_us_col = str_init(T_PORTUS_COL);
56 str t_spi_pc_col = str_init(T_SPIPC_COL);
57 str t_spi_ps_col = str_init(T_SPIPS_COL);
58 str t_spi_uc_col = str_init(T_SPIUC_COL);
59 str t_spi_us_col = str_init(T_SPIUS_COL);
60
61 t_reusable_buffer service_route_buffer = {0,0,0};
62 t_reusable_buffer impu_buffer = {0,0,0};
63
connect_db(const str * db_url)64 int connect_db(const str *db_url)
65 {
66 if (ul_dbh) { /* we've obviously already connected... */
67 LM_WARN("DB connection already open... continuing\n");
68 return 0;
69 }
70
71 if ((ul_dbh = ul_dbf.init(db_url)) == 0)
72 return -1;
73
74 LM_DBG("Successfully connected to DB and returned DB handle ptr %p\n", ul_dbh);
75 return 0;
76 }
77
init_db(const str * db_url,int db_update_period,int fetch_num_rows)78 int init_db(const str *db_url, int db_update_period, int fetch_num_rows)
79 {
80 /* Find a database module */
81 if (db_bind_mod(db_url, &ul_dbf) < 0){
82 LM_ERR("Unable to bind to a database driver\n");
83 return -1;
84 }
85
86 if (connect_db(db_url)!=0){
87 LM_ERR("unable to connect to the database\n");
88 return -1;
89 }
90
91 if (!DB_CAPABILITY(ul_dbf, DB_CAP_ALL)) {
92 LM_ERR("database module does not implement all functions needed by the module\n");
93 return -1;
94 }
95
96 ul_dbf.close(ul_dbh);
97 ul_dbh = 0;
98
99 return 0;
100 }
101
destroy_db()102 void destroy_db()
103 {
104 /* close the DB connection */
105 if (ul_dbh) {
106 ul_dbf.close(ul_dbh);
107 ul_dbh = 0;
108 }
109 }
110
use_location_pcscf_table(str * domain)111 int use_location_pcscf_table(str* domain)
112 {
113 if(!ul_dbh){
114 LM_ERR("invalid database handle\n");
115 return -1;
116 }
117
118 if (ul_dbf.use_table(ul_dbh, domain) < 0) {
119 LM_ERR("Error in use_table\n");
120 return -1;
121 }
122
123 return 0;
124 }
125
db_update_pcontact(pcontact_t * _c)126 int db_update_pcontact(pcontact_t* _c)
127 {
128 str impus, service_routes;
129
130 db_val_t match_values[2];
131 db_key_t match_keys[2] = { &aor_col, &received_port_col };
132 db_op_t op[2];
133 db_key_t update_keys[8] = { &expires_col, ®_state_col,
134 &service_routes_col, &received_col,
135 &received_port_col, &received_proto_col,
136 &rx_session_id_col, &public_ids_col };
137 db_val_t values[8];
138
139 LM_DBG("updating pcontact: aor[%.*s], received port %u\n", _c->aor.len, _c->aor.s, _c->received_port);
140
141 VAL_TYPE(match_values) = DB1_STR;
142 VAL_NULL(match_values) = 0;
143 VAL_STR(match_values) = _c->aor;
144
145 VAL_TYPE(match_values + 1) = DB1_INT;
146 VAL_NULL(match_values + 1) = 0;
147 VAL_INT(match_values + 1) = _c->received_port;
148
149 op[0]=OP_EQ;
150 op[1]=OP_EQ;
151
152 if (use_location_pcscf_table(_c->domain) < 0) {
153 LM_ERR("Error trying to use table %.*s\n", _c->domain->len, _c->domain->s);
154 return -1;
155 }
156
157 VAL_TYPE(values) = DB1_DATETIME;
158 VAL_TIME(values) = _c->expires;
159 VAL_NULL(values) = 0;
160
161 VAL_TYPE(values + 1)= DB1_INT;
162 VAL_NULL(values + 1)= 0;
163 VAL_INT(values + 1) = _c->reg_state;
164
165 str empty_str = str_init("");
166 if (_c->service_routes) {
167 service_routes.len = service_routes_as_string(_c, &service_route_buffer);
168 service_routes.s = service_route_buffer.buf;
169 }
170 SET_STR_VALUE(values + 2, (_c->service_routes)?service_routes:empty_str);
171 VAL_TYPE(values + 2) = DB1_STR;
172 VAL_NULL(values + 2) = 0;
173
174 SET_STR_VALUE(values + 3, _c->received_host);
175 VAL_TYPE(values + 3) = DB1_STR;
176 VAL_NULL(values + 3) = 0;
177
178 VAL_TYPE(values + 4)= DB1_INT;
179 VAL_NULL(values + 4)= 0;
180 VAL_INT(values + 4) = _c->received_port;
181
182 VAL_TYPE(values + 5)= DB1_INT;
183 VAL_NULL(values + 5)= 0;
184 VAL_INT(values + 5) = _c->received_proto;
185
186 VAL_TYPE(values + 6) = DB1_STR;
187 SET_PROPER_NULL_FLAG(_c->rx_session_id, values, 6);
188 LM_DBG("Trying to set rx session id: %.*s\n", _c->rx_session_id.len, _c->rx_session_id.s);
189 SET_STR_VALUE(values + 6, _c->rx_session_id);
190
191 /* add the public identities */
192 impus.len = impus_as_string(_c, &impu_buffer);
193 impus.s = impu_buffer.buf;
194 VAL_TYPE(values + 7) = DB1_STR;
195 SET_PROPER_NULL_FLAG(impus, values, 7);
196 SET_STR_VALUE(values + 7, impus);
197
198 if((ul_dbf.update(ul_dbh, match_keys, op, match_values, update_keys,values, 2, 8)) !=0){
199 LM_ERR("could not update database info\n");
200 return -1;
201 }
202
203 if (ul_dbf.affected_rows && ul_dbf.affected_rows(ul_dbh) == 0) {
204 LM_DBG("no existing rows for an update... doing insert\n");
205 if (db_insert_pcontact(_c) != 0) {
206 LM_ERR("Failed to insert a pcontact on update\n");
207 }
208 }
209
210 return 0;
211 }
212
db_delete_pcontact(pcontact_t * _c)213 int db_delete_pcontact(pcontact_t* _c)
214 {
215 LM_DBG("Trying to delete contact: aor[%.*s], received port %u\n", _c->aor.len, _c->aor.s, _c->received_port);
216 db_val_t values[2];
217 db_key_t match_keys[2] = { &aor_col, &received_port_col };
218
219 VAL_TYPE(values) = DB1_STR;
220 VAL_NULL(values) = 0;
221 SET_STR_VALUE(values, _c->aor);
222
223 VAL_TYPE(values + 1) = DB1_INT;
224 VAL_NULL(values + 1) = 0;
225 VAL_INT(values + 1) = _c->received_port;
226
227 if (use_location_pcscf_table(_c->domain) < 0) {
228 LM_ERR("Error trying to use table %.*s\n", _c->domain->len, _c->domain->s);
229 return -1;
230 }
231
232 if(ul_dbf.delete(ul_dbh, match_keys, 0, values, 2) < 0) {
233 LM_ERR("Failed to delete database information: aor[%.*s], received port %u, rx_session_id=[%.*s]\n",
234 _c->aor.len, _c->aor.s,
235 _c->received_port,
236 _c->rx_session_id.len, _c->rx_session_id.s);
237 return -1;
238 }
239
240 return 0;
241 }
242
db_insert_pcontact(struct pcontact * _c)243 int db_insert_pcontact(struct pcontact* _c)
244 {
245 str empty_str = str_init("");
246 str impus, service_routes;
247
248 db_key_t keys[16] = {
249 &domain_col,
250 &aor_col,
251 &received_col,
252 &received_port_col, &received_proto_col,
253 &path_col, &rinstance_col,
254 &rx_session_id_col, ®_state_col,
255 &expires_col, &service_routes_col,
256 &socket_col, &public_ids_col, &host_col, &port_col, &protocol_col
257 };
258 db_val_t values[16];
259
260 VAL_TYPE(GET_FIELD_IDX(values, LP_DOMAIN_IDX)) = DB1_STR;
261 VAL_TYPE(GET_FIELD_IDX(values, LP_AOR_IDX)) = DB1_STR;
262 VAL_TYPE(GET_FIELD_IDX(values, LP_RECEIVED_IDX)) = DB1_STR;
263 VAL_TYPE(GET_FIELD_IDX(values, LP_RECEIVED_PORT_IDX)) = DB1_INT;
264 VAL_TYPE(GET_FIELD_IDX(values, LP_RECEIVED_PROTO_IDX)) = DB1_INT;
265 VAL_TYPE(GET_FIELD_IDX(values, LP_PATH_IDX)) = DB1_STR;
266 VAL_TYPE(GET_FIELD_IDX(values, LP_RINSTANCE_IDX)) = DB1_STR;
267 VAL_TYPE(GET_FIELD_IDX(values, LP_RX_SESSION_ID_IDX)) = DB1_STR;
268 VAL_TYPE(GET_FIELD_IDX(values, LP_REG_STATE_IDX)) = DB1_INT;
269 VAL_TYPE(GET_FIELD_IDX(values, LP_EXPIRES_IDX)) = DB1_DATETIME;
270 VAL_TYPE(GET_FIELD_IDX(values, LP_SERVICE_ROUTES_IDX)) = DB1_STR;
271 VAL_TYPE(GET_FIELD_IDX(values, LP_SOCKET_IDX)) = DB1_STR;
272 VAL_TYPE(GET_FIELD_IDX(values, LP_PUBLIC_IPS_IDX)) = DB1_STR;
273 VAL_TYPE(GET_FIELD_IDX(values, LP_HOST_IDX)) = DB1_STR;
274 VAL_TYPE(GET_FIELD_IDX(values, LP_PORT_IDX)) = DB1_INT;
275 VAL_TYPE(GET_FIELD_IDX(values, LP_PROTOCOL_IDX)) = DB1_INT;
276
277
278 SET_STR_VALUE(GET_FIELD_IDX(values, LP_DOMAIN_IDX), (*_c->domain));
279 SET_STR_VALUE(GET_FIELD_IDX(values, LP_AOR_IDX), _c->aor); //TODO: need to clean AOR
280 SET_STR_VALUE(GET_FIELD_IDX(values, LP_RECEIVED_IDX), _c->received_host);
281 SET_STR_VALUE(GET_FIELD_IDX(values, LP_HOST_IDX), _c->via_host);
282
283 SET_PROPER_NULL_FLAG((*_c->domain), values, LP_DOMAIN_IDX);
284 SET_PROPER_NULL_FLAG(_c->aor, values, LP_AOR_IDX);
285 SET_PROPER_NULL_FLAG(_c->received_host, values, LP_RECEIVED_IDX);
286 SET_PROPER_NULL_FLAG(_c->via_host, values, LP_HOST_IDX);
287
288 VAL_INT(GET_FIELD_IDX(values, LP_RECEIVED_PORT_IDX)) = _c->received_port;
289 VAL_INT(GET_FIELD_IDX(values, LP_RECEIVED_PROTO_IDX)) = _c->received_proto;
290 VAL_NULL(GET_FIELD_IDX(values, LP_RECEIVED_PORT_IDX)) = 0;
291 VAL_NULL(GET_FIELD_IDX(values, LP_RECEIVED_PROTO_IDX)) = 0;
292 VAL_INT(GET_FIELD_IDX(values, LP_PORT_IDX)) = _c->via_port;
293 VAL_INT(GET_FIELD_IDX(values, LP_PROTOCOL_IDX)) = _c->via_proto;
294 VAL_NULL(GET_FIELD_IDX(values, LP_PORT_IDX)) = 0;
295 VAL_NULL(GET_FIELD_IDX(values, LP_PROTOCOL_IDX)) = 0;
296
297 SET_STR_VALUE(GET_FIELD_IDX(values, LP_PATH_IDX), _c->path);
298 SET_STR_VALUE(GET_FIELD_IDX(values, LP_RINSTANCE_IDX), _c->rinstance);
299 SET_STR_VALUE(GET_FIELD_IDX(values, LP_RX_SESSION_ID_IDX), _c->rx_session_id);
300 SET_PROPER_NULL_FLAG(_c->path, values, LP_PATH_IDX);
301 SET_PROPER_NULL_FLAG(_c->rinstance, values, LP_RINSTANCE_IDX);
302 SET_PROPER_NULL_FLAG(_c->rx_session_id, values, LP_RX_SESSION_ID_IDX);
303
304 VAL_DOUBLE(GET_FIELD_IDX(values, LP_REG_STATE_IDX)) = _c->reg_state;
305 VAL_TIME(GET_FIELD_IDX(values, LP_EXPIRES_IDX)) = _c->expires;
306 VAL_NULL(GET_FIELD_IDX(values, LP_REG_STATE_IDX)) = 0;
307 VAL_NULL(GET_FIELD_IDX(values, LP_EXPIRES_IDX)) = 0;
308
309 SET_STR_VALUE(GET_FIELD_IDX(values, LP_SERVICE_ROUTES_IDX), _c->service_routes?(*_c->service_routes):empty_str);
310 VAL_NULL(GET_FIELD_IDX(values, LP_SERVICE_ROUTES_IDX)) = 1;
311 SET_STR_VALUE(GET_FIELD_IDX(values, LP_SOCKET_IDX), _c->sock?_c->sock->sock_str:empty_str);
312 VAL_NULL(GET_FIELD_IDX(values, LP_SOCKET_IDX)) = 1;
313
314 if (_c->service_routes) {
315 SET_PROPER_NULL_FLAG((*_c->service_routes), values, LP_SERVICE_ROUTES_IDX);
316 }
317 else {
318 VAL_NULL(GET_FIELD_IDX(values, LP_SERVICE_ROUTES_IDX)) = 1;
319 }
320
321 if (_c->sock) {
322 SET_PROPER_NULL_FLAG(_c->sock->sock_str, values, LP_SOCKET_IDX);
323 } else {
324 VAL_NULL(GET_FIELD_IDX(values, LP_SOCKET_IDX)) = 1;
325 }
326
327 /* add the public identities */
328 impus.len = impus_as_string(_c, &impu_buffer);
329 impus.s = impu_buffer.buf;
330 SET_PROPER_NULL_FLAG(impus, values, LP_PUBLIC_IPS_IDX);
331 SET_STR_VALUE(GET_FIELD_IDX(values, LP_PUBLIC_IPS_IDX), impus);
332
333 /* add service routes */
334 service_routes.len = service_routes_as_string(_c, &service_route_buffer);
335 service_routes.s = service_route_buffer.buf;
336 SET_PROPER_NULL_FLAG(service_routes, values, LP_SERVICE_ROUTES_IDX);
337 SET_STR_VALUE(GET_FIELD_IDX(values, LP_SERVICE_ROUTES_IDX), service_routes);
338
339 if (use_location_pcscf_table(_c->domain) < 0) {
340 LM_ERR("Error trying to use table %.*s\n", _c->domain->len, _c->domain->s);
341 return -1;
342 }
343
344 if (ul_dbf.insert(ul_dbh, keys, values, 15) < 0) {
345 LM_ERR("inserting contact in db failed\n");
346 return -1;
347 }
348
349 return 0;
350 }
351
db_update_pcontact_security_temp(struct pcontact * _c,security_type _t,security_t * _s)352 int db_update_pcontact_security_temp(struct pcontact* _c, security_type _t, security_t* _s) {
353 db_val_t match_values[2];
354 db_key_t match_keys[2] = { &aor_col, &received_port_col };
355 db_op_t op[2];
356
357 db_key_t update_keys[15] = { &t_security_type_col, &t_protocol_col,
358 &t_mode_col, &t_ck_col, &t_ik_col, &t_ealg_col, &t_ialg_col, &t_port_pc_col, &t_port_ps_col, &t_port_uc_col,
359 &t_port_us_col, &t_spi_pc_col, &t_spi_ps_col, &t_spi_uc_col, &t_spi_us_col };
360 db_val_t values[15];
361
362 LM_CRIT("updating temp security for pcontact: aor[%.*s], received port %u\n", _c->aor.len, _c->aor.s, _c->received_port);
363
364 VAL_TYPE(match_values) = DB1_STR;
365 VAL_NULL(match_values) = 0;
366 VAL_STR(match_values) = _c->aor;
367
368 VAL_TYPE(match_values + 1) = DB1_INT;
369 VAL_NULL(match_values + 1) = 0;
370 VAL_INT(match_values + 1) = _c->received_port;
371
372 op[0]=OP_EQ;
373 op[1]=OP_EQ;
374
375 if (use_location_pcscf_table(_c->domain) < 0) {
376 LM_ERR("Error trying to use table %.*s\n", _c->domain->len, _c->domain->s);
377 return -1;
378 }
379
380 VAL_TYPE(values) = DB1_INT;
381 VAL_TIME(values) = _s?_s->type:0;
382 VAL_NULL(values) = 0;
383
384 switch (_t) {
385 case SECURITY_IPSEC: {
386 ipsec_t* ipsec = _s?_s->data.ipsec:0;
387 str s_empty = {0,0};
388 int i = 1;
389 VAL_TYPE(values + i) = DB1_STR;
390 VAL_NULL(values + i) = ipsec?0:1;
391 VAL_STR(values + i) = ipsec?ipsec->prot:s_empty;
392
393 VAL_TYPE(values + ++i) = DB1_STR;
394 VAL_NULL(values + i) = ipsec?0:1;
395 VAL_STR(values + i) = ipsec?ipsec->mod:s_empty;
396
397 VAL_TYPE(values + ++i) = DB1_STR;
398 VAL_NULL(values + i) = ipsec?0:1;
399 VAL_STR(values + i) = ipsec?ipsec->ck:s_empty;
400
401 VAL_TYPE(values + ++i) = DB1_STR;
402 VAL_NULL(values + i) = ipsec?0:1;
403 VAL_STR(values + i) = ipsec?ipsec->ik:s_empty;
404
405 VAL_TYPE(values + ++i) = DB1_STR;
406 VAL_NULL(values + i) = ipsec?0:1;
407 VAL_STR(values + i) = ipsec?ipsec->ealg:s_empty;
408
409 VAL_TYPE(values + ++i) = DB1_STR;
410 VAL_NULL(values + i) = ipsec?0:1;
411 VAL_STR(values + i) = ipsec?ipsec->alg:s_empty;
412
413 VAL_TYPE(values + ++i) = DB1_INT;
414 VAL_NULL(values + i) = ipsec?0:1;
415 VAL_INT(values + i) = ipsec?ipsec->port_pc:0;
416
417 VAL_TYPE(values + ++i) = DB1_INT;
418 VAL_NULL(values + i) = ipsec?0:1;
419 VAL_INT(values + i) = ipsec?ipsec->port_ps:0;
420
421 VAL_TYPE(values + ++i) = DB1_INT;
422 VAL_NULL(values + i) = ipsec?0:1;
423 VAL_INT(values + i) = ipsec?ipsec->port_uc:0;
424
425 VAL_TYPE(values + ++i) = DB1_INT;
426 VAL_NULL(values + i) = ipsec?0:1;
427 VAL_INT(values + i) = ipsec?ipsec->port_us:0;
428
429 VAL_TYPE(values + ++i) = DB1_BIGINT;
430 VAL_NULL(values + i) = ipsec?0:1;
431 VAL_BIGINT(values + i) = ipsec?ipsec->spi_pc:0;
432
433 VAL_TYPE(values + ++i) = DB1_BIGINT;
434 VAL_NULL(values + i) = ipsec?0:1;
435 VAL_BIGINT(values + i) = ipsec?ipsec->spi_ps:0;
436
437 VAL_TYPE(values + ++i) = DB1_BIGINT;
438 VAL_NULL(values + i) = ipsec?0:1;
439 VAL_BIGINT(values + i) = ipsec?ipsec->spi_uc:0;
440
441 VAL_TYPE(values + ++i) = DB1_BIGINT;
442 VAL_NULL(values + i) = ipsec?0:1;
443 VAL_BIGINT(values + i) = ipsec?ipsec->spi_us:0;
444
445 if ((ul_dbf.update(ul_dbh, match_keys, op, match_values, update_keys, values, 2, 15)) != 0) {
446 LM_ERR("could not update database info\n");
447 return -1;
448 }
449
450 if (ul_dbf.affected_rows && ul_dbf.affected_rows(ul_dbh) == 0) {
451 LM_CRIT("no existing rows for an update... doing insert\n");
452 if (db_insert_pcontact(_c) != 0) {
453 LM_ERR("Failed to insert a pcontact on update\n");
454 }
455 }
456 break;
457 }
458 default:
459 LM_WARN("not yet implemented or unknown security type\n");
460 return -1;
461 }
462
463 return 0;
464 }
465
db_update_pcontact_security(struct pcontact * _c,security_type _t,security_t * _s)466 int db_update_pcontact_security(struct pcontact* _c, security_type _t, security_t* _s) {
467 db_val_t match_values[2];
468 db_key_t match_keys[2] = { &aor_col, &received_port_col };
469 db_op_t op[2];
470
471 db_key_t update_keys[15] = { &security_type_col, &protocol_col,
472 &mode_col, &ck_col, &ik_col, &ealg_col, &ialg_col, &port_pc_col, &port_ps_col, &port_uc_col,
473 &port_us_col, &spi_pc_col, &spi_ps_col, &spi_uc_col, &spi_us_col };
474 db_val_t values[15];
475
476 LM_DBG("updating security for pcontact: aor[%.*s], received port %u\n", _c->aor.len, _c->aor.s, _c->received_port);
477
478 VAL_TYPE(match_values) = DB1_STR;
479 VAL_NULL(match_values) = 0;
480 VAL_STR(match_values) = _c->aor;
481
482 VAL_TYPE(match_values + 1) = DB1_INT;
483 VAL_NULL(match_values + 1) = 0;
484 VAL_INT(match_values + 1) = _c->received_port;
485
486 op[0]=OP_EQ;
487 op[1]=OP_EQ;
488
489 if (use_location_pcscf_table(_c->domain) < 0) {
490 LM_ERR("Error trying to use table %.*s\n", _c->domain->len, _c->domain->s);
491 return -1;
492 }
493
494 VAL_TYPE(values) = DB1_INT;
495 VAL_TIME(values) = _s?_s->type:0;
496 VAL_NULL(values) = 0;
497
498 switch (_t) {
499 case SECURITY_IPSEC: {
500 ipsec_t* ipsec = _s?_s->data.ipsec:0;
501 int i = 1;
502 str s_empty = {0,0};
503 VAL_TYPE(values + i) = DB1_STR;
504 VAL_NULL(values + i) = ipsec?0:1;
505 VAL_STR(values + i) = ipsec?ipsec->prot:s_empty;
506
507 VAL_TYPE(values + ++i) = DB1_STR;
508 VAL_NULL(values + i) = ipsec?0:1;
509 VAL_STR(values + i) = ipsec?ipsec->mod:s_empty;
510
511 VAL_TYPE(values + ++i) = DB1_STR;
512 VAL_NULL(values + i) = ipsec?0:1;
513 VAL_STR(values + i) = ipsec?ipsec->ck:s_empty;
514
515 VAL_TYPE(values + ++i) = DB1_STR;
516 VAL_NULL(values + i) = ipsec?0:1;
517 VAL_STR(values + i) = ipsec?ipsec->ik:s_empty;
518
519 VAL_TYPE(values + ++i) = DB1_STR;
520 VAL_NULL(values + i) = ipsec?0:1;
521 VAL_STR(values + i) = ipsec?ipsec->ealg:s_empty;
522
523 VAL_TYPE(values + ++i) = DB1_STR;
524 VAL_NULL(values + i) = ipsec?0:1;
525 VAL_STR(values + i) = ipsec?ipsec->alg:s_empty;
526
527 VAL_TYPE(values + ++i) = DB1_INT;
528 VAL_NULL(values + i) = ipsec?0:1;
529 VAL_INT(values + i) = ipsec?ipsec->port_pc:0;
530
531 VAL_TYPE(values + ++i) = DB1_INT;
532 VAL_NULL(values + i) = ipsec?0:1;
533 VAL_INT(values + i) = ipsec?ipsec->port_ps:0;
534
535 VAL_TYPE(values + ++i) = DB1_INT;
536 VAL_NULL(values + i) = ipsec?0:1;
537 VAL_INT(values + i) = ipsec?ipsec->port_uc:0;
538
539 VAL_TYPE(values + ++i) = DB1_INT;
540 VAL_NULL(values + i) = ipsec?0:1;
541 VAL_INT(values + i) = ipsec?ipsec->port_us:0;
542
543 VAL_TYPE(values + ++i) = DB1_BIGINT;
544 VAL_NULL(values + i) = ipsec?0:1;
545 VAL_BIGINT(values + i) = ipsec?ipsec->spi_pc:0;
546
547 VAL_TYPE(values + ++i) = DB1_BIGINT;
548 VAL_NULL(values + i) = ipsec?0:1;
549 VAL_BIGINT(values + i) = ipsec?ipsec->spi_ps:0;
550
551 VAL_TYPE(values + ++i) = DB1_BIGINT;
552 VAL_NULL(values + i) = ipsec?0:1;
553 VAL_BIGINT(values + i) = ipsec?ipsec->spi_uc:0;
554
555 VAL_TYPE(values + ++i) = DB1_BIGINT;
556 VAL_NULL(values + i) = ipsec?0:1;
557 VAL_BIGINT(values + i) = ipsec?ipsec->spi_us:0;
558
559 if ((ul_dbf.update(ul_dbh, match_keys, op, match_values, update_keys, values, 2, 15)) != 0) {
560 LM_ERR("could not update database info\n");
561 return -1;
562 }
563
564 if (ul_dbf.affected_rows && ul_dbf.affected_rows(ul_dbh) == 0) {
565 LM_DBG("no existing rows for an update... doing insert\n");
566 if (db_insert_pcontact(_c) != 0) {
567 LM_ERR("Failed to insert a pcontact on update\n");
568 }
569 }
570 break;
571 }
572 default:
573 LM_WARN("not yet implemented or unknown security type\n");
574 return -1;
575 }
576
577 return 0;
578 }
579
580 /* take a contact structure and a pointer to some memory and returns a list of public identities in the format
581 * <impu1><impu2>....<impu(n)>
582 * make sure p already has memory allocated
583 * returns the length of the string (list)
584 * the string list itself will be available in p
585 */
impus_as_string(struct pcontact * _c,t_reusable_buffer * buffer)586 int impus_as_string(struct pcontact* _c, t_reusable_buffer* buffer) {
587 ppublic_t* impu;
588 int len = 0;
589 char *p;
590
591 impu = _c->head;
592 while (impu) {
593 len += 2 + impu->public_identity.len;
594 impu = impu->next;
595 }
596
597 if (!buffer->buf || buffer->buf_len == 0 || len > buffer->buf_len) {
598 if (buffer->buf) {
599 pkg_free(buffer->buf);
600 }
601 buffer->buf = (char*) pkg_malloc(len);
602 if (!buffer->buf) {
603 LM_CRIT("unable to allocate pkg memory\n");
604 return 0;
605 }
606 buffer->buf_len = len;
607 }
608
609 impu = _c->head;
610 p = buffer->buf;
611 while (impu) {
612 *p++ = '<';
613 memcpy(p, impu->public_identity.s, impu->public_identity.len);
614 p += impu->public_identity.len;
615 *p++ = '>';
616 impu = impu->next;
617 }
618
619 return len;
620 }
621
622 /* take a contact structure and a pointer to some memory and returns a list of public identities in the format
623 * <impu1><impu2>....<impu(n)>
624 * make sure p already has memory allocated
625 * returns the length of the string (list)
626 * the string list itself will be available in p
627 */
service_routes_as_string(struct pcontact * _c,t_reusable_buffer * buffer)628 int service_routes_as_string(struct pcontact* _c, t_reusable_buffer *buffer) {
629 int i;
630 int len = 0;
631 char *p;
632 for (i=0; i<_c->num_service_routes; i++) {
633 len += 2 + _c->service_routes[i].len;
634 }
635
636 if (!buffer->buf || buffer->buf_len==0 || len > buffer->buf_len) {
637 if (buffer->buf) {
638 pkg_free(buffer->buf);
639 }
640 buffer->buf = (char*)pkg_malloc(len);
641 if (!buffer->buf) {
642 LM_CRIT("unable to allocate pkg memory\n");
643 return 0;
644 }
645 buffer->buf_len = len;
646 }
647
648 p = buffer->buf;
649 for (i=0; i<_c->num_service_routes; i++) {
650 *p = '<';
651 p++;
652 memcpy(p, _c->service_routes[i].s, _c->service_routes[i].len);
653 p+=_c->service_routes[i].len;
654 *p = '>';
655 p++;
656 }
657
658 return len;
659 }
660
free_service_route_buf(void)661 void free_service_route_buf(void)
662 {
663 if (service_route_buffer.buf) {
664 pkg_free(service_route_buffer.buf);
665 service_route_buffer.data_len = 0;
666 service_route_buffer.buf_len = 0;
667 service_route_buffer.buf = 0;
668 }
669 }
670
free_impu_buf(void)671 void free_impu_buf(void) {
672 if (impu_buffer.buf) {
673 pkg_free(impu_buffer.buf);
674 impu_buffer.data_len = 0;
675 impu_buffer.buf_len = 0;
676 impu_buffer.buf = 0;
677 }
678 }
679
680