Bringing up TLS connections working.
[libradsec.git] / lib / conn.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 <assert.h>
8 #include <event2/event.h>
9 #include <radsec/radsec.h>
10 #include <radsec/radsec-impl.h>
11
12 int
13 rs_conn_create (struct rs_context *ctx, struct rs_connection **conn,
14                 const char *config)
15 {
16   struct rs_connection *c;
17
18   c = (struct rs_connection *) malloc (sizeof(struct rs_connection));
19   if (c)
20     {
21       memset (c, 0, sizeof(struct rs_connection));
22       c->ctx = ctx;
23       if (config)
24         {
25           struct rs_realm *r = rs_conf_find_realm (ctx, config);
26           if (r)
27             {
28               struct rs_peer *p;
29
30               c->type = r->type;
31               c->peers = r->peers; /* FIXME: Copy instead?  */
32               for (p = c->peers; p; p = p->next)
33                 p->conn = c;
34             }
35         }
36     }
37   if (conn)
38     *conn = c;
39   return c ? RSE_OK : rs_err_ctx_push (ctx, RSE_NOMEM, NULL);
40 }
41
42 void
43 rs_conn_set_type (struct rs_connection *conn, rs_conn_type_t type)
44 {
45   conn->type = type;
46 }
47
48
49 struct rs_error *
50 _rs_resolv (struct evutil_addrinfo **addr, rs_conn_type_t type,
51             const char *hostname, const char *service)
52 {
53   int err;
54   struct evutil_addrinfo hints, *res = NULL;
55
56   memset (&hints, 0, sizeof(struct evutil_addrinfo));
57   hints.ai_family = AF_INET;   /* IPv4 only.  TODO: Set AF_UNSPEC.  */
58   hints.ai_flags = AI_ADDRCONFIG;
59   switch (type)
60     {
61     case RS_CONN_TYPE_NONE:
62       return _rs_err_create (RSE_INVALID_CONN, __FILE__, __LINE__, NULL, NULL);
63     case RS_CONN_TYPE_TCP:
64       /* Fall through.  */
65     case RS_CONN_TYPE_TLS:
66       hints.ai_socktype = SOCK_STREAM;
67       hints.ai_protocol = IPPROTO_TCP;
68       break;
69     case RS_CONN_TYPE_UDP:
70       /* Fall through.  */
71     case RS_CONN_TYPE_DTLS:
72       hints.ai_socktype = SOCK_DGRAM;
73       hints.ai_protocol = IPPROTO_UDP;
74       break;
75     }
76   err = evutil_getaddrinfo (hostname, service, &hints, &res);
77   if (err)
78     return _rs_err_create (RSE_BADADDR, __FILE__, __LINE__,
79                            "%s:%s: bad host name or service name (%s)",
80                            hostname, service, evutil_gai_strerror(err));
81   *addr = res;                  /* Simply use first result.  */
82   return NULL;
83 }
84
85 int
86 rs_conn_add_listener (struct rs_connection *conn, rs_conn_type_t type,
87                       const char *hostname, int port)
88 {
89   return rs_err_conn_push_fl (conn, RSE_NOSYS, __FILE__, __LINE__,
90                               "%s: NYI", __func__);
91 }
92
93 void
94 rs_conn_destroy (struct rs_connection *conn)
95 {
96   struct rs_peer *p;
97
98 #warning "TODO: Disconnect active_peer."
99
100   for (p = conn->peers; p; p = p->next)
101     {
102       if (p->addr)
103         evutil_freeaddrinfo (p->addr);
104       if (p->secret)
105         rs_free (conn->ctx, p->secret);
106     }
107
108   if (conn->evb)
109     event_base_free (conn->evb);
110 }
111
112 int
113 rs_conn_set_eventbase (struct rs_connection *conn, struct event_base *eb)
114 {
115   return rs_err_conn_push_fl (conn, RSE_NOSYS, __FILE__, __LINE__,
116                               "%s: NYI", __func__);
117 }
118
119 int
120 rs_conn_set_callbacks (struct rs_connection *conn, struct rs_conn_callbacks *cb)
121 {
122   return rs_err_conn_push_fl (conn, RSE_NOSYS, __FILE__, __LINE__,
123                               "%s: NYI", __func__);
124 }
125
126 int
127 rs_conn_select_server (struct rs_connection *conn, const char *name)
128 {
129   return rs_err_conn_push_fl (conn, RSE_NOSYS, __FILE__, __LINE__,
130                               "%s: NYI", __func__);
131 }
132
133 int
134 rs_conn_get_current_server (struct rs_connection *conn, const char *name,
135                             size_t buflen)
136 {
137   return rs_err_conn_push_fl (conn, RSE_NOSYS, __FILE__, __LINE__,
138                               "%s: NYI", __func__);
139 }
140
141 int rs_conn_fd (struct rs_connection *conn)
142 {
143   assert (conn);
144   assert (conn->active_peer);
145   return conn->active_peer->fd;
146 }