patch: udp_connect() api to take peer address, cleanup error checking

This commit is contained in:
Alfred E. Heggestad 2013-10-11 17:41:32 +00:00
parent 2831d72502
commit 570bb426f2
4 changed files with 42 additions and 33 deletions

View file

@ -195,7 +195,6 @@ struct dnsc_conf {
uint32_t tcp_hash_size;
uint32_t conn_timeout; /* in [ms] */
uint32_t idle_timeout; /* in [ms] */
bool udp_conn;
};
int dnsc_alloc(struct dnsc **dcpp, const struct dnsc_conf *conf,

View file

@ -17,11 +17,12 @@ struct udp_sock;
* @param arg Handler argument
*/
typedef void (udp_recv_h)(const struct sa *src, struct mbuf *mb, void *arg);
typedef void (udp_error_h)(int err, void *arg);
int udp_listen(struct udp_sock **usp, const struct sa *local,
udp_recv_h *rh, void *arg);
void udp_connect(struct udp_sock *us, bool conn);
int udp_connect(struct udp_sock *us, const struct sa *peer);
int udp_send(struct udp_sock *us, const struct sa *dst, struct mbuf *mb);
int udp_send_anon(const struct sa *dst, struct mbuf *mb);
int udp_local_get(const struct udp_sock *us, struct sa *local);
@ -31,6 +32,7 @@ int udp_sockbuf_set(struct udp_sock *us, int size);
void udp_rxsz_set(struct udp_sock *us, size_t rxsz);
void udp_rxbuf_presz_set(struct udp_sock *us, size_t rx_presz);
void udp_handler_set(struct udp_sock *us, udp_recv_h *rh, void *arg);
void udp_error_handler_set(struct udp_sock *us, udp_error_h *eh);
int udp_thread_attach(struct udp_sock *us);
void udp_thread_detach(struct udp_sock *us);
int udp_sock_fd(const struct udp_sock *us, int af);

View file

@ -91,7 +91,6 @@ static const struct dnsc_conf default_conf = {
TCP_HASH_SIZE,
CONN_TIMEOUT,
IDLE_TIMEOUT,
false
};
@ -861,14 +860,6 @@ int dnsc_alloc(struct dnsc **dcpp, const struct dnsc_conf *conf,
if (err)
goto out;
/* Experimental code:
* Connected UDP sockets will only work if we have one UDP socket
* per UDP server. Connected UDP socket is used to get ICMP
* messages for unreachable DNS Servers.
*/
if (dnsc->conf.udp_conn)
udp_connect(dnsc->us, true);
err = hash_alloc(&dnsc->ht_query, dnsc->conf.query_hash_size);
if (err)
goto out;

View file

@ -63,13 +63,13 @@ enum {
struct udp_sock {
struct list helpers; /**< List of UDP Helpers */
udp_recv_h *rh; /**< Receive handler */
udp_error_h *eh; /**< Error handler */
void *arg; /**< Handler argument */
int fd; /**< Socket file descriptor */
int fd6; /**< IPv6 socket file descriptor */
bool conn; /**< Connected socket flag */
size_t rxsz; /**< Maximum receive chunk size */
size_t rx_presz; /**< Preallocated rx buffer size */
int err; /**< Cached error code */
};
/** Defines a UDP helper */
@ -195,9 +195,8 @@ static void udp_read(struct udp_sock *us, int fd)
goto out;
}
#endif
/* cache error code */
us->err = err;
if (us->eh)
us->eh(err, us->arg);
goto out;
}
@ -396,18 +395,33 @@ int udp_listen(struct udp_sock **usp, const struct sa *local,
/**
* Connect a UDP Socket to its peer, so we can receive ICMP messages.
* Connect a UDP Socket to a specific peer.
* When connected, this UDP Socket will only receive data from that peer.
*
* @param us UDP Socket
* @param conn Connected flag
* @param peer Peer network address
*
* @return 0 if success, otherwise errorcode
*/
void udp_connect(struct udp_sock *us, bool conn)
int udp_connect(struct udp_sock *us, const struct sa *peer)
{
if (!us)
return;
int fd;
us->conn = conn;
if (!us || !peer)
return EINVAL;
/* choose a socket */
if (AF_INET6 == sa_af(peer) && -1 != us->fd6)
fd = us->fd6;
else
fd = us->fd;
if (0 != connect(fd, &peer->u.sa, peer->len))
return errno;
us->conn = true;
return 0;
}
@ -417,13 +431,6 @@ static int udp_send_internal(struct udp_sock *us, const struct sa *dst,
struct sa hdst;
int err = 0, fd;
/* check for error in e.g. connected state */
if (us->err) {
err = us->err;
us->err = 0; /* clear error */
return err;
}
/* choose a socket */
if (AF_INET6 == sa_af(dst) && -1 != us->fd6)
fd = us->fd6;
@ -447,11 +454,6 @@ static int udp_send_internal(struct udp_sock *us, const struct sa *dst,
/* Connected socket? */
if (us->conn) {
if (0 != connect(fd, &dst->u.sa, dst->len)) {
DEBUG_WARNING("send: connect: %m\n", errno);
us->conn = false;
}
if (send(fd, BUF_CAST mb->buf + mb->pos, mb->end - mb->pos,
0) < 0)
return errno;
@ -642,6 +644,21 @@ void udp_handler_set(struct udp_sock *us, udp_recv_h *rh, void *arg)
}
/**
* Set error handler on a UDP Socket
*
* @param us UDP Socket
* @param eh Error handler
*/
void udp_error_handler_set(struct udp_sock *us, udp_error_h *eh)
{
if (!us)
return;
us->eh = eh;
}
/**
* Get the File Descriptor from a UDP Socket
*