1 /* Copyright 2013 NORDUnet A/S. All rights reserved.
2 See LICENSE for licensing information. */
4 #if defined HAVE_CONFIG_H
10 #include <event2/listener.h>
11 #include <radsec/radsec.h>
12 #include <radsec/radsec-impl.h>
20 listener_create (struct rs_context *ctx, struct rs_listener **rootp)
22 struct rs_listener *listener;
24 listener = rs_calloc (ctx, 1, sizeof (*listener));
31 listener->next = (*rootp)->next;
32 (*rootp)->next = listener;
39 listener_accept_cb_ (struct evconnlistener *evconnlistener,
40 evutil_socket_t newfd,
41 struct sockaddr *srcaddr_sa,
46 struct rs_listener *l = NULL;
47 struct rs_connection *newconn = NULL;
48 struct rs_context *ctx = NULL;
49 struct rs_peer *clients = NULL;
51 l = (struct rs_listener *) user_data;
53 assert (l->base_.magic == RS_CONN_MAGIC_LISTENER);
54 assert (l->evlistener == evconnlistener);
60 char host[80], port[80];
61 getnameinfo (srcaddr_sa, srcaddr_len, host, sizeof(host),
62 port, sizeof(port), 0);
63 rs_debug (("%s: incoming connection from %s:%s\n", __func__, host, port));
68 Application needs to specify acceptable clients -- we need to verify
69 src addr in the UDP case and x509 client cert in the TLS case. A list
70 of peers with proper pointers to realms should be a good way of doing
73 Ask the application for a list of acceptable clients. Default to
74 accepting any potential configured client block in the realm of the
75 listener. Note that this for this to be an opption, the application
76 must have read a config file. If there is no configuration, reject the
79 if (l->callbacks.client_filter_cb)
80 clients = l->callbacks.client_filter_cb (l, TO_BASE_CONN(l)->user_data);
82 clients = connbase_get_peers (TO_BASE_CONN(l));
85 rs_debug (("%s: didn't get a client list for listener %p\n",
89 rs_debug (("%s: using client list %p\n", __func__, clients));
91 err = rs_conn_create (ctx, &newconn, NULL);
94 rs_debug (("%s: failed creating a new struct rs_connection: %d\n",
96 return; /* FIXME: Verify that this is handled. */
100 /* TODO: Picking the very first peer is not really what we want to
101 do. For UDP, we can look at src ip and try to find a matching
102 peer. For TLS, it's worse because we don't have the certificate
103 until we've accepted the TCP connection. */
104 TO_BASE_CONN(newconn)->realm = clients->realm;
105 newconn->active_peer = clients;
107 TO_BASE_CONN(newconn)->fd = newfd;
108 TO_BASE_CONN(newconn)->transport = TO_BASE_CONN(l)->realm->type;
109 err = event_init_bufferevent (newconn);
112 rs_debug (("%s: failed init bev: %d\n", __func__, err));
116 /* Create a message and set up a read event. This installs the
117 callback performing the TLS verification. */
119 struct rs_message *msg = NULL;
120 err = rs_message_create (newconn, &msg);
122 abort (); /* FIXME */
123 conn_add_read_event (newconn, msg);
126 if (l->callbacks.new_conn_cb)
127 l->callbacks.new_conn_cb (newconn, TO_BASE_CONN(l)->user_data);
128 return; /* Success. */
131 rs_conn_destroy (newconn);
132 if (l->callbacks.error_cb)
133 l->callbacks.error_cb (newconn, TO_BASE_CONN(l)->user_data);
137 listener_err_cb_ (struct evconnlistener *listener, void *user_data)
139 rs_debug (("%s: FIXME: handle error\n", __func__));
142 /* Public functions. */
144 rs_listener_create (struct rs_context *ctx,
145 struct rs_listener **listener_out,
149 struct rs_listener *listener = NULL;
153 listener = rs_calloc (ctx, 1, sizeof (*listener));
154 if (listener == NULL)
155 return rs_err_ctx_push_fl (ctx, RSE_NOMEM, __FILE__, __LINE__, NULL);
156 conn_init (ctx, TO_BASE_CONN (listener), RS_CONN_OBJTYPE_LISTENER);
157 err = conn_configure (ctx, TO_BASE_CONN (listener), config);
162 *listener_out = listener;
167 rs_free (ctx, listener);
172 rs_listener_set_callbacks (struct rs_listener *listener,
173 const struct rs_listener_callbacks *cb,
177 TO_BASE_CONN(listener)->user_data = user_data;
178 memcpy (&listener->callbacks, cb, sizeof (listener->callbacks));
182 rs_listener_listen (struct rs_listener *listener)
185 struct rs_conn_base *connbase = NULL;
187 connbase = TO_BASE_CONN (listener);
189 err = event_init_eventbase (connbase);
192 err = event_init_socket (connbase, connbase->realm->local_addr);
200 rs_debug (("%s: setting SO_LINGER 0s on fd %d\n", __func__, connbase->fd));
201 assert (0 == setsockopt (connbase->fd, SOL_SOCKET, SO_LINGER,
202 (void*)&l, sizeof(l)));
209 rs_listener_dispatch (const struct rs_listener *listener)
212 assert (TO_BASE_CONN(listener)->ctx);
213 return event_base_dispatch (TO_BASE_CONN(listener)->ctx->evb);
217 rs_listener_close (struct rs_listener *l)
219 int err = baseconn_close (TO_BASE_CONN (l));
224 rs_listener_get_eventbase (const struct rs_listener *l)
226 assert (TO_BASE_CONN (l));
227 assert (TO_BASE_CONN (l)->ctx);
228 return TO_BASE_CONN (l)->ctx->evb;
232 rs_listener_get_fd (const struct rs_listener *l)
234 assert (TO_BASE_CONN (l));
235 return TO_BASE_CONN (l)->fd;