Merge branch 'milestone/monitoring' into jennifer/request_id
[trust_router.git] / tid / tid_resp.c
1 /*
2  * Copyright (c) 2012, JANET(UK)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. Neither the name of JANET(UK) nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31  * OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  */
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <assert.h>
38 #include <talloc.h>
39
40 #include <trust_router/tr_dh.h>
41 #include <tid_internal.h>
42
43 static int tid_resp_destructor(void *obj)
44 {
45   TID_RESP *resp=talloc_get_type_abort(obj, TID_RESP);
46   if (resp->err_msg!=NULL)
47     tr_free_name(resp->err_msg);
48   if (resp->rp_realm!=NULL)
49     tr_free_name(resp->rp_realm);
50   if (resp->realm!=NULL)
51     tr_free_name(resp->realm);
52   if (resp->comm!=NULL)
53     tr_free_name(resp->comm);
54   if (resp->orig_coi!=NULL)
55     tr_free_name(resp->orig_coi);
56   if (resp->request_id!=NULL)
57     tr_free_name(resp->request_id);
58   return 0;
59 }
60
61 TID_RESP *tid_resp_new(TALLOC_CTX *mem_ctx)
62 {
63   TID_RESP *resp=talloc(mem_ctx, TID_RESP);
64   if (resp!=NULL) {
65     resp->result=TID_ERROR;
66     resp->err_msg=NULL;
67     resp->rp_realm=NULL;
68     resp->realm=NULL;
69     resp->comm=NULL;
70     resp->cons=NULL;
71     resp->orig_coi=NULL;
72     resp->servers=NULL;
73     resp->request_id=NULL;
74     resp->error_path=NULL;
75     talloc_set_destructor((void *)resp, tid_resp_destructor);
76   }
77   return resp;
78 }
79
80 void tid_resp_free(TID_RESP *resp)
81 {
82   if (resp)
83     talloc_free(resp);
84 }
85
86 /**
87  * Allocate a new copy of a TID_RESP
88  *
89  * @param mem_ctx
90  * @param resp
91  * @return
92  */
93 TID_RESP *tid_resp_dup(TALLOC_CTX *mem_ctx, TID_RESP *resp)
94 {
95   TID_RESP *newresp=NULL;
96
97   if (resp==NULL)
98     return NULL;
99
100   newresp=tid_resp_new(mem_ctx);
101
102   if (NULL!=newresp) {
103     tid_resp_cpy(newresp, resp);
104   }
105   return newresp;
106 }
107
108 /**
109  * Copy contents of one TID_RESP to an existing TID_RESP
110  *
111  * @param dst
112  * @param src
113  * @return TID_SUCCESS on success, error code on error
114  */
115 TID_RC tid_resp_cpy(TID_RESP *dst, TID_RESP *src)
116 {
117   tid_resp_set_result(dst, tid_resp_get_result(src));
118   tid_resp_set_err_msg(dst,
119                        tr_dup_name(tid_resp_get_err_msg(src)));
120   tid_resp_set_rp_realm(dst,
121                         tr_dup_name(tid_resp_get_rp_realm(src)));
122   tid_resp_set_realm(dst,
123                      tr_dup_name(tid_resp_get_realm(src)));
124   tid_resp_set_comm(dst,
125                     tr_dup_name(tid_resp_get_comm(src)));
126   tid_resp_set_cons(dst, src->cons);
127   tid_resp_set_orig_coi(dst,
128                         tr_dup_name(tid_resp_get_orig_coi(src)));
129   dst->servers = tid_srvr_blk_dup(dst, src->servers);
130   tid_resp_set_error_path(dst, src->error_path);
131
132   return TID_SUCCESS;
133 }
134
135 TR_EXPORT int tid_resp_get_result(TID_RESP *resp)
136 {
137   return(resp->result);
138 }
139
140 void tid_resp_set_result(TID_RESP *resp, int result)
141 {
142   resp->result = result;
143 }
144
145 TR_EXPORT TR_NAME *tid_resp_get_err_msg(TID_RESP *resp)
146 {
147   return(resp->err_msg);
148 }
149
150 void tid_resp_set_err_msg(TID_RESP *resp, TR_NAME *err_msg)
151 {
152   if (resp->err_msg!=NULL)
153     tr_free_name(resp->err_msg);
154
155   resp->err_msg = err_msg;
156 }
157
158 TR_EXPORT TR_NAME *tid_resp_get_rp_realm(TID_RESP *resp)
159 {
160   return(resp->rp_realm);
161 }
162
163 void tid_resp_set_rp_realm(TID_RESP *resp, TR_NAME *rp_realm)
164 {
165   resp->rp_realm = rp_realm;
166 }
167
168 TR_EXPORT TR_NAME *tid_resp_get_realm(TID_RESP *resp)
169 {
170   return(resp->realm);
171 }
172
173 void tid_resp_set_realm(TID_RESP *resp, TR_NAME *realm)
174 {
175   resp->realm = realm;
176 }
177
178 TR_EXPORT TR_NAME *tid_resp_get_comm(TID_RESP *resp)
179 {
180   return(resp->comm);
181 }
182
183 void tid_resp_set_comm(TID_RESP *resp, TR_NAME *comm)
184 {
185   resp->comm = comm;
186 }
187
188 TR_EXPORT TR_NAME *tid_resp_get_orig_coi(TID_RESP *resp)
189 {
190   return(resp->orig_coi);
191 }
192
193 void tid_resp_set_orig_coi(TID_RESP *resp, TR_NAME *orig_coi)
194 {
195   resp->orig_coi = orig_coi;
196 }
197
198 TR_EXPORT TR_NAME *tid_resp_get_request_id(TID_RESP *resp)
199 {
200   return(resp->request_id);
201 }
202
203 void tid_resp_set_request_id(TID_RESP *resp, TR_NAME *request_id)
204 {
205   resp->request_id = request_id;
206 }
207
208 TR_EXPORT TID_SRVR_BLK *tid_resp_get_server(TID_RESP *resp,
209                                             size_t index)
210 {
211   TID_SRVR_BLK *this=NULL;
212   assert(resp);
213
214   for (this=resp->servers; index>0; index--, this=this->next) {}
215
216   return this;
217 }
218
219 size_t tid_resp_get_num_servers(const TID_RESP *resp)
220 {
221   size_t count=0;
222   TID_SRVR_BLK *this=NULL;
223
224   assert(resp!=NULL);
225   for (count=0, this=resp->servers; this!=NULL; count++, this=this->next) {}
226   return count;
227 }
228
229 static int tid_srvr_blk_destructor(void *obj)
230 {
231   TID_SRVR_BLK *srvr=talloc_get_type_abort(obj, TID_SRVR_BLK);
232
233   if (srvr->key_name!=NULL)
234     tr_free_name(srvr->key_name);
235   if (srvr->aaa_server_dh!=NULL)
236     tr_destroy_dh_params(srvr->aaa_server_dh);
237   if (srvr->path!=NULL)
238     json_decref((json_t *)(srvr->path));
239   return 0;
240 }
241
242 TR_EXPORT TID_SRVR_BLK *tid_srvr_blk_new(TALLOC_CTX *mem_ctx)
243 {
244   TID_SRVR_BLK *srvr=talloc(mem_ctx, TID_SRVR_BLK);
245
246   if (srvr!=NULL) {
247     srvr->next=NULL;
248     srvr->aaa_server_addr=NULL;
249     srvr->key_name=NULL;
250     srvr->aaa_server_dh=NULL;
251     srvr->key_expiration=(GTimeVal){0};
252     srvr->path=NULL;
253     talloc_set_destructor((void *)srvr, tid_srvr_blk_destructor);
254   }
255   return srvr;
256 }
257
258 TR_EXPORT void tid_srvr_blk_free(TID_SRVR_BLK *srvr)
259 {
260   talloc_free(srvr);
261 }
262
263 TR_EXPORT TID_SRVR_BLK *tid_srvr_blk_dup(TALLOC_CTX *mem_ctx, TID_SRVR_BLK *srvr)
264 {
265   TID_SRVR_BLK *new=NULL;
266
267   if (srvr==NULL)
268     return NULL;
269
270   new=tid_srvr_blk_new(mem_ctx);
271   if (new!=NULL) {
272     if (srvr->aaa_server_addr!=NULL)
273       new->aaa_server_addr=talloc_strdup(new, srvr->aaa_server_addr);
274     new->key_name=tr_dup_name(srvr->key_name);
275     new->aaa_server_dh=tr_dh_dup(srvr->aaa_server_dh);
276     new->key_expiration=srvr->key_expiration;
277     
278     tid_srvr_blk_set_path(new, srvr->path);
279
280     tid_srvr_blk_add(new->next, tid_srvr_blk_dup(mem_ctx, srvr->next));
281   }
282   return new;
283 }
284
285 /* use the macro */
286 TR_EXPORT TID_SRVR_BLK *tid_srvr_blk_add_func(TID_SRVR_BLK *head, TID_SRVR_BLK *new)
287 {
288   TID_SRVR_BLK *this=head;
289
290   if (head==NULL)
291     return new;
292
293   while (this->next!=NULL)
294     this=this->next;
295   
296   this->next=new;
297   while (this!=NULL) {
298     talloc_steal(head, this);
299     this=this->next;
300   }
301   return head;
302 }
303
304 TR_EXPORT void tid_srvr_blk_set_path(TID_SRVR_BLK *block, TID_PATH *path)
305 {
306   if (block->path!=NULL)
307     json_decref((json_t *)(block->path));
308   block->path=path;
309   if (block->path!=NULL)
310     json_incref((json_t *)(block->path));
311 }
312
313 TR_EXPORT const TID_PATH *tid_srvr_get_path( const TID_SRVR_BLK *block)
314 {
315   if (!block)
316     return NULL;
317   return block->path;
318 }
319
320 TR_EXPORT int tid_srvr_get_key_expiration(const TID_SRVR_BLK *block, struct timeval *tv_out)
321 {
322   if ((block==NULL) || (tv_out==NULL))
323     return -1; /* error */
324
325   tv_out->tv_sec=block->key_expiration.tv_sec;
326   tv_out->tv_usec=block->key_expiration.tv_usec;
327   return 0;
328 }
329
330
331 TR_EXPORT void tid_resp_set_cons(TID_RESP *resp, TR_CONSTRAINT_SET *cons)
332 {
333   json_t *jc=(json_t *)cons;
334
335   if (resp->cons!=NULL)
336     json_decref((json_t *) (resp->cons));
337
338   resp->cons=(TR_CONSTRAINT_SET *)jc;
339   if (jc!=NULL)
340     json_incref(jc);
341 }
342
343 TR_EXPORT void tid_resp_set_error_path(TID_RESP *resp, json_t *ep)
344 {
345   if (resp->error_path!=NULL)
346     json_decref(resp->error_path);
347   resp->error_path=ep;
348   if (resp->error_path!=NULL)
349     json_incref(resp->error_path);
350 }
351
352 TR_EXPORT const TID_PATH *tid_resp_get_error_path(const TID_RESP *resp)
353 {
354   if (!resp)
355     return NULL;
356   return (const TID_PATH *)(resp->error_path);
357 }
358
359 TR_EXPORT const TID_PATH *tid_resp_get_a_path(const TID_RESP *const_resp)
360 {
361   size_t index;
362   TID_SRVR_BLK *server;
363   TID_RESP *resp = (TID_RESP *) const_resp;
364   if (!resp)
365     return NULL;
366
367   if (resp->error_path)
368     return (const TID_PATH *)(resp->error_path);
369   tid_resp_servers_foreach( resp, server, index) {
370     if (server->path)
371       return server->path;
372   }
373   return NULL;
374   
375 }