Don't have the connection freeing peers -- it's the contexts responsibility.
[libradsec.git] / lib / radsec.c
1 /* See the file COPYING for licensing information.  */
2
3 #if defined HAVE_CONFIG_H
4 #include <config.h>
5 #endif
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <stdint.h>
10 #include <string.h>
11 #include <libgen.h>
12 #include <assert.h>
13
14 #include <freeradius/libradius.h>
15 #include <event2/event.h>
16 #include <event2/util.h>
17 #include <radsec/radsec.h>
18 #include <radsec/radsec-impl.h>
19 #if defined (RS_ENABLE_TLS)
20 #include <regex.h>
21 #include "debug.h"
22 #include "rsp_list.h"
23 #include "../radsecproxy.h"
24 #endif
25 #include "rsp_debug.h"
26
27 int
28 rs_context_create(struct rs_context **ctx, const char *dict)
29 {
30   int err = RSE_OK;
31   struct rs_context *h;
32   char *buf1 = NULL, *buf2 = NULL;
33   char *dir, *fn;
34
35   assert (dict);
36
37   if (ctx)
38     *ctx = NULL;
39   h = (struct rs_context *) malloc (sizeof(struct rs_context));
40   if (!h)
41     return RSE_NOMEM;
42
43   /* Initialize freeradius dictionary.  */
44   buf1 = malloc (strlen (dict) + 1);
45   buf2 = malloc (strlen (dict) + 1);
46   if (!buf1 || !buf2)
47     {
48       err = RSE_NOMEM;
49       goto err_out;
50     }
51   strcpy (buf1, dict);
52   dir = dirname (buf1);
53   strcpy (buf2, dict);
54   fn = basename (buf2);
55   if (dict_init (dir, fn) < 0)
56     {
57       err = RSE_SOME_ERROR;
58       goto err_out;
59     }
60   free (buf1);
61   free (buf2);
62
63 #if defined (RS_ENABLE_TLS)
64   ssl_init ();
65 #endif
66 #if defined (DEBUG)
67   fr_log_fp = stderr;
68   fr_debug_flag = 1;
69 #endif
70   debug_init ("libradsec");     /* radsecproxy compat, FIXME: remove */
71
72   memset (h, 0, sizeof(struct rs_context));
73   fr_randinit (&h->fr_randctx, 0);
74   fr_rand_seed (NULL, 0);
75
76   if (ctx)
77     *ctx = h;
78
79   return RSE_OK;
80
81  err_out:
82   if (buf1)
83     free (buf1);
84   if (buf2)
85     free (buf2);
86   if (h)
87     free (h);
88   return err;
89 }
90
91 struct rs_peer *
92 _rs_peer_create (struct rs_context *ctx, struct rs_peer **rootp)
93 {
94   struct rs_peer *p;
95
96   p = (struct rs_peer *) rs_malloc (ctx, sizeof(*p));
97   if (p)
98     {
99       memset (p, 0, sizeof(struct rs_peer));
100       if (*rootp)
101         {
102           p->next = (*rootp)->next;
103           (*rootp)->next = p;
104         }
105       else
106         *rootp = p;
107     }
108   return p;
109 }
110
111 static void
112 _rs_peer_destroy (struct rs_peer *p)
113 {
114   assert (p);
115   assert (p->conn);
116   assert (p->conn->ctx);
117   /* NOTE: The peer object doesn't own its connection (conn).  */
118   if (p->addr)
119     {
120       evutil_freeaddrinfo (p->addr);
121       p->addr = NULL;
122     }
123   if (p->secret)
124     rs_free (p->conn->ctx, p->secret);
125   rs_free (p->conn->ctx, p);
126 }
127
128 void rs_context_destroy(struct rs_context *ctx)
129 {
130   struct rs_realm *r = NULL;
131   struct rs_peer *p = NULL;
132
133   for (r = ctx->realms; r; )
134     {
135       struct rs_realm *tmp = r;
136       for (p = r->peers; p; )
137         {
138           struct rs_peer *tmp = p;
139           p = p->next;
140           _rs_peer_destroy (tmp);
141         }
142       r = r->next;
143       rs_free (ctx, tmp);
144     }
145   rs_free (ctx, ctx);
146 }
147
148 int rs_context_set_alloc_scheme(struct rs_context *ctx,
149                                 struct rs_alloc_scheme *scheme)
150 {
151   return rs_err_ctx_push_fl (ctx, RSE_NOSYS, __FILE__, __LINE__,
152                              "%s: NYI", __func__);
153 }