1 /* Copyright 2011-2013 NORDUnet A/S. All rights reserved.
2 See LICENSE for licensing information. */
4 #if defined HAVE_CONFIG_H
12 #include <event2/event.h>
13 #include <event2/listener.h>
14 #include <event2/bufferevent.h>
15 #if defined (RS_ENABLE_TLS)
16 #include <event2/bufferevent_ssl.h>
17 #include <openssl/err.h>
19 #include <radsec/radsec.h>
20 #include <radsec/radsec-impl.h>
23 #if defined (RS_ENABLE_TLS)
35 extern int _event_debug_mode_on;
39 _evlog_cb (int severity, const char *msg)
44 case _EVENT_LOG_DEBUG:
45 #if !defined (DEBUG_LEVENT)
63 fprintf (stderr, "libevent: [%s] %s\n", sevstr, msg); /* FIXME: stderr? */
67 event_conn_timeout_cb (int fd, short event, void *data)
69 struct rs_connection *conn = NULL;
72 conn = (struct rs_connection *) data;
74 if (event & EV_TIMEOUT)
76 rs_debug (("%s: connection timeout on %p (fd %d) connecting to %p\n",
77 __func__, conn, conn->base_.fd, conn->active_peer));
78 conn->state = RS_CONN_STATE_UNDEFINED;
79 rs_err_conn_push_fl (conn, RSE_TIMEOUT_CONN, __FILE__, __LINE__, NULL);
80 event_loopbreak (conn);
85 event_retransmit_timeout_cb (int fd, short event, void *data)
87 struct rs_connection *conn = NULL;
90 conn = (struct rs_connection *) data;
92 if (event & EV_TIMEOUT)
94 rs_debug (("%s: retransmission timeout on %p (fd %d) sending to %p\n",
95 __func__, conn, conn->base_.fd, conn->active_peer));
96 rs_err_conn_push_fl (conn, RSE_TIMEOUT_IO, __FILE__, __LINE__, NULL);
97 event_loopbreak (conn);
101 /* FIXME: event_ is actually not such a great prefix given that we
102 link with libevent which exports 113 symbols prefixed 'event_'. */
104 event_init_socket (struct rs_conn_base *connbase, struct rs_peer *p)
106 if (connbase->fd != -1)
112 /* Resolve potential DNS name for peer. */
113 if (p->addr_cache == NULL)
115 struct rs_error *err =
116 rs_resolve (&p->addr_cache, p->realm->type, p->hostname, p->service);
118 return err_connbase_push_err (connbase, err);
121 /* Create the socket and make it non-blocking. */
122 connbase->fd = socket (p->addr_cache->ai_family,
123 p->addr_cache->ai_socktype,
124 p->addr_cache->ai_protocol);
125 if (connbase->fd < 0)
126 return rs_err_connbase_push_fl (connbase, RSE_SOCKERR, __FILE__, __LINE__,
128 errno, strerror (errno));
129 if (evutil_make_socket_nonblocking (connbase->fd) < 0)
131 evutil_closesocket (connbase->fd);
133 return rs_err_connbase_push_fl (connbase, RSE_SOCKERR, __FILE__, __LINE__,
134 "evutil_make_socket_nonblocking: %d (%s)",
135 errno, strerror (errno));
138 /* If we're inititalising the socket for a listener, bind to the
140 if (connbase->magic == RS_CONN_MAGIC_LISTENER)
142 assert (p->realm->type == connbase->transport);
143 if (p->realm->type == RS_CONN_TYPE_TLS
144 || p->realm->type == RS_CONN_TYPE_TCP)
146 struct rs_listener *listener = TO_LISTENER_CONN (connbase);
147 listener->evlistener =
148 evconnlistener_new_bind (listener->base_.ctx->evb,
150 listener, LEV_OPT_REUSEABLE,
152 p->addr_cache->ai_addr,
153 p->addr_cache->ai_addrlen);
154 if (listener->evlistener == NULL)
155 return rs_err_connbase_push (connbase, RSE_EVENT,
156 "evconnlistener_new_bind: %d (%s)",
157 errno, strerror (errno));
159 evconnlistener_set_error_cb (listener->evlistener, listener_err_cb_);
163 return rs_err_connbase_push_fl (connbase, RSE_NOSYS,
164 __FILE__, __LINE__, NULL);
172 event_init_bufferevent (struct rs_connection *conn)
174 struct rs_conn_base *connbase = NULL;
176 connbase = TO_BASE_CONN(conn);
181 if (connbase->transport == RS_CONN_TYPE_TCP)
183 connbase->bev = bufferevent_socket_new (connbase->ctx->evb,
186 return rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,
187 "bufferevent_socket_new");
189 #if defined (RS_ENABLE_TLS)
190 else if (connbase->transport == RS_CONN_TYPE_TLS)
192 enum bufferevent_ssl_state bev_ssl_state;
194 if (rs_tls_init (conn))
196 bev_ssl_state = conn_originating_p (conn)
197 ? BUFFEREVENT_SSL_CONNECTING : BUFFEREVENT_SSL_ACCEPTING;
199 /* It would be convenient to pass BEV_OPT_CLOSE_ON_FREE in last
200 argument (options) but things seem to break when
201 be_openssl_ctrl() (in libevent) calls SSL_set_bio() after
202 BIO_new_socket() with flag=1. */
204 bufferevent_openssl_socket_new (connbase->ctx->evb, connbase->fd,
205 conn->tls_ssl, bev_ssl_state, 0);
207 return rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,
208 "bufferevent_openssl_socket_new");
210 #endif /* RS_ENABLE_TLS */
213 return rs_err_conn_push_fl (conn, RSE_INTERNAL, __FILE__, __LINE__,
214 "%s: unknown connection type: %d", __func__,
215 connbase->transport);
222 event_do_connect (struct rs_connection *conn)
225 struct sockaddr *peer_addr;
229 assert (conn->active_peer);
230 assert (conn->active_peer->addr_cache);
231 peer_addr = conn->active_peer->addr_cache->ai_addr;
232 peer_addrlen = conn->active_peer->addr_cache->ai_addrlen;
234 /* We don't connect listeners. */
235 assert (conn->base_.magic == RS_CONN_MAGIC_GENERIC);
239 char host[80], serv[80];
241 getnameinfo (peer_addr, peer_addrlen,
244 0 /* NI_NUMERICHOST|NI_NUMERICSERV*/);
245 rs_debug (("%s: connecting to %s:%s\n", __func__, host, serv));
249 if (conn->base_.bev) /* TCP */
251 conn_activate_timeout (conn); /* Connect timeout. */
252 err = bufferevent_socket_connect (conn->base_.bev,
253 peer_addr, peer_addrlen);
255 rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,
256 "bufferevent_socket_connect: %s",
257 evutil_gai_strerror (err));
259 conn->state = RS_CONN_STATE_CONNECTING;
263 err = connect (conn->base_.fd, peer_addr, peer_addrlen);
266 sockerr = evutil_socket_geterror (conn->base_.fd);
267 rs_debug (("%s: %d: connect: %d (%s)\n", __func__,
269 sockerr, evutil_socket_error_to_string (sockerr)));
270 rs_err_conn_push (conn, RSE_SOCKERR,
271 "%d: connect: %d (%s)", conn->base_.fd,
272 sockerr, evutil_socket_error_to_string (sockerr));
275 conn->state = RS_CONN_STATE_CONNECTING;
280 event_loopbreak (struct rs_connection *conn)
282 int err = event_base_loopbreak (TO_BASE_CONN(conn)->ctx->evb);
284 rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,
285 "event_base_loopbreak: %s",
286 evutil_gai_strerror (err)); /* FIXME: really gai_strerror? */
292 event_on_disconnect (struct rs_connection *conn)
294 conn->state = RS_CONN_STATE_UNDEFINED;
295 rs_debug (("%s: %p disconnected\n", __func__, conn->active_peer));
296 if (conn->callbacks.disconnected_cb)
297 conn->callbacks.disconnected_cb (conn->base_.user_data);
300 /** Internal connect event for originating connections. Returns 0 on
301 success and -1 on TLS certificate verification failure. */
303 event_on_connect_orig (struct rs_connection *conn, struct rs_message *msg)
305 assert (conn->state == RS_CONN_STATE_CONNECTING);
306 assert (conn->active_peer);
308 #if defined (RS_ENABLE_TLS)
309 if (conn_type_tls_p (conn) && !conn_cred_psk (conn))
310 if (tls_verify_cert (conn) != RSE_OK)
312 rs_debug (("%s: server cert verification failed\n", __func__));
315 #endif /* RS_ENABLE_TLS */
317 conn->state = RS_CONN_STATE_CONNECTED;
318 rs_debug (("%s: %p connected\n", __func__, conn->active_peer));
320 if (conn->callbacks.connected_cb)
321 conn->callbacks.connected_cb (conn->base_.user_data);
324 message_do_send (msg);
331 event_on_connect_term (struct rs_connection *conn, struct rs_message *msg)
333 /* TODO: verify client */
334 conn->state = RS_CONN_STATE_CONNECTED;
335 rs_debug (("%s: WARNING: not checking client cert!!!\n", __func__));
336 if (conn->callbacks.connected_cb)
337 conn->callbacks.connected_cb (conn->base_.user_data);
342 event_init_eventbase (struct rs_conn_base *connbase)
345 assert (connbase->ctx);
346 if (connbase->ctx->evb)
350 if (!_event_debug_mode_on)
351 event_enable_debug_mode ();
353 event_set_log_callback (_evlog_cb);
354 connbase->ctx->evb = event_base_new ();
355 if (!connbase->ctx->evb)
356 return rs_err_connbase_push_fl (connbase, RSE_EVENT, __FILE__, __LINE__,