diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/conn.c | 17 | ||||
| -rw-r--r-- | lib/event.c | 43 | ||||
| -rw-r--r-- | lib/event.h | 2 | ||||
| -rw-r--r-- | lib/packet.c | 6 | ||||
| -rw-r--r-- | lib/peer.h | 1 | ||||
| -rw-r--r-- | lib/radsec.c | 49 | ||||
| -rw-r--r-- | lib/send.c | 4 | ||||
| -rw-r--r-- | lib/tcp.c | 31 | ||||
| -rw-r--r-- | lib/tcp.h | 2 | ||||
| -rw-r--r-- | lib/udp.c | 15 | ||||
| -rw-r--r-- | lib/udp.h | 1 | 
11 files changed, 129 insertions, 42 deletions
| @@ -282,3 +282,20 @@ rs_conn_set_timeout(struct rs_connection *conn, struct timeval *tv)    assert (tv);    conn->timeout = *tv;  } + +int +conn_activate_timeout (struct rs_connection *conn) +{ +  assert (conn); +  assert (conn->tev); +  assert (conn->evb); +  if (conn->timeout.tv_sec || conn->timeout.tv_usec) +    { +      rs_debug (("%s: activating timer: %d.%d\n", __func__, +		 conn->timeout.tv_sec, conn->timeout.tv_usec)); +      if (evtimer_add (conn->tev, &conn->timeout)) +	return rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__, +				    "evtimer_add: %d", errno); +    } +  return RSE_OK; +} diff --git a/lib/event.c b/lib/event.c index 55a7e6b..5afba98 100644 --- a/lib/event.c +++ b/lib/event.c @@ -21,6 +21,7 @@  #endif  #include "event.h"  #include "packet.h" +#include "conn.h"  #include "debug.h"  static void @@ -51,6 +52,41 @@ _evlog_cb (int severity, const char *msg)    fprintf (stderr, "libevent: [%s] %s\n", sevstr, msg); /* FIXME: stderr?  */  } +void +event_conn_timeout_cb (int fd, short event, void *data) +{ +  struct rs_connection *conn = NULL; + +  assert (data); +  conn = (struct rs_connection *) data; + +  if (event & EV_TIMEOUT) +    { +      rs_debug (("%s: connection timeout on %p (fd %d) connecting to %p\n", +		 __func__, conn, conn->fd, conn->active_peer)); +      conn->is_connecting = 0; +      rs_err_conn_push_fl (conn, RSE_TIMEOUT_CONN, __FILE__, __LINE__, NULL); +      event_loopbreak (conn); +    } +} + +void +event_retransmit_timeout_cb (int fd, short event, void *data) +{ +  struct rs_connection *conn = NULL; + +  assert (data); +  conn = (struct rs_connection *) data; + +  if (event & EV_TIMEOUT) +    { +      rs_debug (("%s: retransmission timeout on %p (fd %d) sending to %p\n", +		 __func__, conn, conn->fd, conn->active_peer)); +      rs_err_conn_push_fl (conn, RSE_TIMEOUT_IO, __FILE__, __LINE__, NULL); +      event_loopbreak (conn); +    } +} +  int  event_init_socket (struct rs_connection *conn, struct rs_peer *p)  { @@ -138,7 +174,7 @@ event_do_connect (struct rs_connection *conn)    if (p->conn->bev)		/* TCP */      { -      tcp_set_connect_timeout (conn); +      conn_activate_timeout (conn); /* Connect timeout.  */        err = bufferevent_socket_connect (p->conn->bev, p->addr->ai_addr,  					p->addr->ai_addrlen);        if (err < 0) @@ -191,10 +227,10 @@ event_on_connect (struct rs_connection *conn, struct rs_packet *pkt)    assert (!conn->is_connecting);    conn->is_connected = 1;    rs_debug (("%s: %p connected\n", __func__, conn->active_peer)); -  if (conn->tev) -    evtimer_del (conn->tev); +    if (conn->callbacks.connected_cb)      conn->callbacks.connected_cb (conn->user_data); +    if (pkt)      packet_do_send (pkt);  } @@ -202,6 +238,7 @@ event_on_connect (struct rs_connection *conn, struct rs_packet *pkt)  int  event_init_eventbase (struct rs_connection *conn)  { +  assert (conn);    if (conn->evb)      return RSE_OK; diff --git a/lib/event.h b/lib/event.h index e5ea90c..e042599 100644 --- a/lib/event.h +++ b/lib/event.h @@ -8,3 +8,5 @@ int event_init_eventbase (struct rs_connection *conn);  int event_init_socket (struct rs_connection *conn, struct rs_peer *p);  int event_init_bufferevent (struct rs_connection *conn, struct rs_peer *peer);  void event_do_connect (struct rs_connection *conn); +void event_conn_timeout_cb (int fd, short event, void *data); +void event_retransmit_timeout_cb (int fd, short event, void *data); diff --git a/lib/packet.c b/lib/packet.c index 799234f..2611b46 100644 --- a/lib/packet.c +++ b/lib/packet.c @@ -88,7 +88,7 @@ packet_do_send (struct rs_packet *pkt)    }  #endif -  if (pkt->conn->bev) +  if (pkt->conn->bev)		/* TCP.  */      {        int err = bufferevent_write (pkt->conn->bev, pkt->rpkt->data,  				   pkt->rpkt->data_len); @@ -97,13 +97,15 @@ packet_do_send (struct rs_packet *pkt)  				    "bufferevent_write: %s",  				    evutil_gai_strerror (err));      } -  else +  else				/* UDP.  */      {        struct rs_packet **pp = &pkt->conn->out_queue;        while (*pp && (*pp)->next)  	*pp = (*pp)->next;        *pp = pkt; + +      conn_activate_timeout (pkt->conn); /* Retransmission timer.  */      }    return RSE_OK; @@ -1,4 +1,5 @@  /* Copyright 2011 NORDUnet A/S. All rights reserved.     See the file COPYING for licensing information.  */ +struct rs_peer *peer_create (struct rs_context *ctx, struct rs_peer **rootp);  struct rs_peer *peer_pick_peer (struct rs_connection *conn); diff --git a/lib/radsec.c b/lib/radsec.c index ddd4edd..ec43b2f 100644 --- a/lib/radsec.c +++ b/lib/radsec.c @@ -20,6 +20,7 @@  #if defined (RS_ENABLE_TLS)  #include <regex.h>  #include "debug.h" +#include "err.h"  #include "rsp_list.h"  #include "../radsecproxy.h"  #endif @@ -91,24 +92,44 @@ rs_context_create (struct rs_context **ctx, const char *dict)    return err;  } -struct rs_peer * -_rs_peer_create (struct rs_context *ctx, struct rs_peer **rootp) +struct rs_error *	   /* FIXME: Return int as all the others?  */ +rs_resolv (struct evutil_addrinfo **addr, +	   rs_conn_type_t type, +	   const char *hostname, +	   const char *service)  { -  struct rs_peer *p; +  int err; +  struct evutil_addrinfo hints, *res = NULL; -  p = (struct rs_peer *) rs_malloc (ctx, sizeof(*p)); -  if (p) +  memset (&hints, 0, sizeof(struct evutil_addrinfo)); +  hints.ai_family = AF_INET;   /* IPv4 only.  TODO: Set AF_UNSPEC.  */ +  hints.ai_flags = AI_ADDRCONFIG; +  switch (type)      { -      memset (p, 0, sizeof(struct rs_peer)); -      if (*rootp) -	{ -	  p->next = (*rootp)->next; -	  (*rootp)->next = p; -	} -      else -	*rootp = p; +    case RS_CONN_TYPE_NONE: +      return err_create (RSE_INVALID_CONN, __FILE__, __LINE__, NULL, NULL); +    case RS_CONN_TYPE_TCP: +      /* Fall through.  */ +    case RS_CONN_TYPE_TLS: +      hints.ai_socktype = SOCK_STREAM; +      hints.ai_protocol = IPPROTO_TCP; +      break; +    case RS_CONN_TYPE_UDP: +      /* Fall through.  */ +    case RS_CONN_TYPE_DTLS: +      hints.ai_socktype = SOCK_DGRAM; +      hints.ai_protocol = IPPROTO_UDP; +      break; +    default: +      return err_create (RSE_INVALID_CONN, __FILE__, __LINE__, NULL, NULL);      } -  return p; +  err = evutil_getaddrinfo (hostname, service, &hints, &res); +  if (err) +    return err_create (RSE_BADADDR, __FILE__, __LINE__, +		       "%s:%s: bad host name or service name (%s)", +		       hostname, service, evutil_gai_strerror(err)); +  *addr = res;			/* Simply use first result.  */ +  return NULL;  }  static void @@ -35,6 +35,8 @@ _conn_open (struct rs_connection *conn, struct rs_packet *pkt)    if (conn->realm->type == RS_CONN_TYPE_TCP        || conn->realm->type == RS_CONN_TYPE_TLS)      { +      if (tcp_init_connect_timer (conn)) +	return -1;        if (event_init_bufferevent (conn, conn->active_peer))  	return -1;      } @@ -42,6 +44,8 @@ _conn_open (struct rs_connection *conn, struct rs_packet *pkt)      {        if (udp_init (conn, pkt))  	return -1; +      if (udp_init_retransmit_timer (conn)) +	return -1;      }    if (!conn->is_connected) @@ -24,24 +24,6 @@  #include <event2/buffer.h>  #endif -static void -_conn_timeout_cb (int fd, short event, void *data) -{ -  struct rs_connection *conn; - -  assert (data); -  conn = (struct rs_connection *) data; - -  if (event & EV_TIMEOUT) -    { -      rs_debug (("%s: connection timeout on %p (fd %d) connecting to %p\n", -		 __func__, conn, conn->fd, conn->active_peer)); -      conn->is_connecting = 0; -      rs_err_conn_push_fl (conn, RSE_TIMEOUT_CONN, __FILE__, __LINE__, NULL); -      event_loopbreak (conn); -    } -} -  /* Read one RADIUS packet header.  Return !0 on error.  A return value     of 0 means that we need more data.  */  static int @@ -191,6 +173,8 @@ tcp_event_cb (struct bufferevent *bev, short events, void *user_data)    conn->is_connecting = 0;    if (events & BEV_EVENT_CONNECTED)      { +      if (conn->tev) +	evtimer_del (conn->tev); /* Cancel connect timer.  */        event_on_connect (conn, pkt);      }    else if (events & BEV_EVENT_EOF) @@ -255,13 +239,16 @@ tcp_write_cb (struct bufferevent *bev, void *ctx)  }  int -tcp_set_connect_timeout (struct rs_connection *conn) +tcp_init_connect_timer (struct rs_connection *conn)  { -  if (!conn->tev) -    conn->tev = evtimer_new (conn->evb, _conn_timeout_cb, conn); +  assert (conn); + +  if (conn->tev) +    event_free (conn->tev); +  conn->tev = evtimer_new (conn->evb, event_conn_timeout_cb, conn);    if (!conn->tev)      return rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,  				"evtimer_new"); -  evtimer_add (conn->tev, &conn->timeout); +    return RSE_OK;  } @@ -4,4 +4,4 @@  void tcp_event_cb (struct bufferevent *bev, short events, void *user_data);  void tcp_read_cb (struct bufferevent *bev, void *user_data);  void tcp_write_cb (struct bufferevent *bev, void *ctx); -int tcp_set_connect_timeout (struct rs_connection *conn); +int tcp_init_connect_timer (struct rs_connection *conn); @@ -107,3 +107,18 @@ udp_init (struct rs_connection *conn, struct rs_packet *pkt)      }    return RSE_OK;  } + +int +udp_init_retransmit_timer (struct rs_connection *conn) +{ +  assert (conn); + +  if (conn->tev) +    event_free (conn->tev); +  conn->tev = evtimer_new (conn->evb, event_retransmit_timeout_cb, conn); +  if (!conn->tev) +    return rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__, +				"evtimer_new"); + +  return RSE_OK; +} @@ -2,3 +2,4 @@     See the file COPYING for licensing information.  */  int udp_init (struct rs_connection *conn, struct rs_packet *pkt); +int udp_init_retransmit_timer (struct rs_connection *conn); | 
