-#include "util.h"
-
-static void setprotoopts(struct commonprotoopts *opts);
-static char **getlistenerargs();
-void *udpserverrd(void *arg);
-int clientradputudp(struct server *server, unsigned char *rad);
-void addclientudp(struct client *client);
-void addserverextraudp(struct clsrvconf *conf);
-void udpsetsrcres();
-void initextraudp();
-
-static const struct protodefs protodefs = {
- "udp",
- NULL, /* secretdefault */
- SOCK_DGRAM, /* socktype */
- "1812", /* portdefault */
- REQUEST_RETRY_COUNT, /* retrycountdefault */
- 10, /* retrycountmax */
- REQUEST_RETRY_INTERVAL, /* retryintervaldefault */
- 60, /* retryintervalmax */
- DUPLICATE_INTERVAL, /* duplicateintervaldefault */
- setprotoopts, /* setprotoopts */
- getlistenerargs, /* getlistenerargs */
- udpserverrd, /* listener */
- NULL, /* connecter */
- NULL, /* clientconnreader */
- clientradputudp, /* clientradput */
- addclientudp, /* addclient */
- addserverextraudp, /* addserverextra */
- udpsetsrcres, /* setsrcres */
- initextraudp /* initextra */
-};
-
-static int client4_sock = -1;
-static int client6_sock = -1;
-static struct gqueue *server_replyq = NULL;
-
-static struct addrinfo *srcres = NULL;
-static uint8_t handle;
-static struct commonprotoopts *protoopts = NULL;
-
-const struct protodefs *udpinit(uint8_t h) {
- handle = h;
- return &protodefs;
-}
-
-static void setprotoopts(struct commonprotoopts *opts) {
- protoopts = opts;
-}
-
-static char **getlistenerargs() {
- return protoopts ? protoopts->listenargs : NULL;
-}
-
-void udpsetsrcres() {
- if (!srcres)
- srcres = resolvepassiveaddrinfo(protoopts ? protoopts->sourcearg : NULL, NULL, protodefs.socktype);
-}
-
-void removeudpclientfromreplyq(struct client *c) {
- struct list_node *n;
- struct request *r;
-
- /* lock the common queue and remove replies for this client */
- pthread_mutex_lock(&c->replyq->mutex);
- for (n = list_first(c->replyq->entries); n; n = list_next(n)) {
- r = (struct request *)n->data;
- if (r->from == c)
- r->from = NULL;
- }
- pthread_mutex_unlock(&c->replyq->mutex);
-}
-
-static int addr_equal(struct sockaddr *a, struct sockaddr *b) {
- switch (a->sa_family) {
- case AF_INET:
- return !memcmp(&((struct sockaddr_in*)a)->sin_addr,
- &((struct sockaddr_in*)b)->sin_addr,
- sizeof(struct in_addr));
- case AF_INET6:
- return IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6*)a)->sin6_addr,
- &((struct sockaddr_in6*)b)->sin6_addr);
- default:
- /* Must not reach */
- return 0;
+#include "event.h"
+#include "compat.h"
+#include "udp.h"
+
+/* Send one packet, the first in queue. */
+static int
+_send (struct rs_connection *conn, int fd)
+{
+ ssize_t r = 0;
+ struct rs_packet *pkt = conn->out_queue;
+
+ assert (pkt->rpkt);
+ assert (pkt->rpkt->data);
+
+ /* Send. */
+ r = compat_send (fd, pkt->rpkt->data, pkt->rpkt->length, 0);
+ if (r == -1)
+ {
+ int sockerr = evutil_socket_geterror (pkt->conn->fd);
+ if (sockerr != EAGAIN)
+ return rs_err_conn_push_fl (pkt->conn, RSE_SOCKERR, __FILE__, __LINE__,
+ "%d: send: %d (%s)", fd, sockerr,
+ evutil_socket_error_to_string (sockerr));