krb5_fulladdr remote_addr;
krb5_address local_addr_buf;
krb5_fulladdr local_addr;
- socklen_t saddr_len;
- socklen_t daddr_len;
struct sockaddr_storage saddr;
struct sockaddr_storage daddr;
aux_addressing_info auxaddr;
goto out;
cc = send_to_from(state->port_fd, response->data,
- (socklen_t) response->length, 0,
- (struct sockaddr *)&state->saddr, state->saddr_len,
- (struct sockaddr *)&state->daddr, state->daddr_len,
- &state->auxaddr);
+ (socklen_t)response->length, 0, ss2sa(&state->saddr),
+ ss2sa(&state->daddr), &state->auxaddr);
if (cc == -1) {
/* Note that the local address (daddr*) has no port number
* info associated with it. */
char daddrbuf[NI_MAXHOST];
int e = errno;
- if (getnameinfo((struct sockaddr *)&state->daddr, state->daddr_len,
+ if (getnameinfo(ss2sa(&state->daddr), sa_socklen(ss2sa(&state->daddr)),
daddrbuf, sizeof(daddrbuf), 0, 0,
NI_NUMERICHOST) != 0) {
strlcpy(daddrbuf, "?", sizeof(daddrbuf));
}
- if (getnameinfo((struct sockaddr *)&state->saddr, state->saddr_len,
+ if (getnameinfo(ss2sa(&state->saddr), sa_socklen(ss2sa(&state->saddr)),
saddrbuf, sizeof(saddrbuf), sportbuf, sizeof(sportbuf),
NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
strlcpy(saddrbuf, "?", sizeof(saddrbuf));
int cc;
struct connection *conn;
struct udp_dispatch_state *state;
+ socklen_t slen;
conn = verto_get_private(ev);
state->port_fd = verto_get_fd(ev);
assert(state->port_fd >= 0);
- state->saddr_len = sizeof(state->saddr);
- state->daddr_len = sizeof(state->daddr);
memset(&state->auxaddr, 0, sizeof(state->auxaddr));
cc = recv_from_to(state->port_fd, state->pktbuf, sizeof(state->pktbuf), 0,
- (struct sockaddr *)&state->saddr, &state->saddr_len,
- (struct sockaddr *)&state->daddr, &state->daddr_len,
- &state->auxaddr);
+ &state->saddr, &state->daddr, &state->auxaddr);
if (cc == -1) {
if (errno != EINTR && errno != EAGAIN
/*
return;
}
- if (state->daddr_len == 0 && conn->type == CONN_UDP) {
+ if (state->daddr.ss_family == AF_UNSPEC && conn->type == CONN_UDP) {
/*
* An address couldn't be obtained, so the PKTINFO option probably
* isn't available. If the socket is bound to a specific address, then
* try to get the address here.
*/
- state->daddr_len = sizeof(state->daddr);
- if (getsockname(state->port_fd, (struct sockaddr *)&state->daddr,
- &state->daddr_len) != 0)
- state->daddr_len = 0;
- /* On failure, keep going anyways. */
+ slen = sizeof(state->daddr);
+ (void)getsockname(state->port_fd, ss2sa(&state->daddr), &slen);
}
state->request.length = cc;
#define check_cmsg_v4_pktinfo check_cmsg_ip_pktinfo
static int
-check_cmsg_ip_pktinfo(struct cmsghdr *cmsgptr, struct sockaddr *to,
- socklen_t *tolen, aux_addressing_info *auxaddr)
+check_cmsg_ip_pktinfo(struct cmsghdr *cmsgptr, struct sockaddr_in *to,
+ aux_addressing_info *auxaddr)
{
struct in_pktinfo *pktinfo;
if (cmsgptr->cmsg_level == IPPROTO_IP &&
- cmsgptr->cmsg_type == IP_PKTINFO &&
- *tolen >= sizeof(struct sockaddr_in)) {
-
- memset(to, 0, sizeof(struct sockaddr_in));
+ cmsgptr->cmsg_type == IP_PKTINFO) {
+ memset(to, 0, sizeof(*to));
pktinfo = cmsg2pktinfo(cmsgptr);
- sa2sin(to)->sin_addr = pktinfo->ipi_addr;
- sa2sin(to)->sin_family = AF_INET;
- *tolen = sizeof(struct sockaddr_in);
+ to->sin_addr = pktinfo->ipi_addr;
+ to->sin_family = AF_INET;
return 1;
}
return 0;
#define check_cmsg_v4_pktinfo check_cmsg_ip_recvdstaddr
static int
-check_cmsg_ip_recvdstaddr(struct cmsghdr *cmsgptr, struct sockaddr *to,
- socklen_t *tolen, aux_addressing_info * auxaddr)
+check_cmsg_ip_recvdstaddr(struct cmsghdr *cmsgptr, struct sockaddr_in *to,
+ aux_addressing_info *auxaddr)
{
- if (cmsgptr->cmsg_level == IPPROTO_IP &&
- cmsgptr->cmsg_type == IP_RECVDSTADDR &&
- *tolen >= sizeof(struct sockaddr_in)) {
- struct in_addr *sin_addr;
+ struct in_addr *sin_addr;
- memset(to, 0, sizeof(struct sockaddr_in));
+ if (cmsgptr->cmsg_level == IPPROTO_IP &&
+ cmsgptr->cmsg_type == IP_RECVDSTADDR) {
+ memset(to, 0, sizeof(*to));
sin_addr = cmsg2sin(cmsgptr);
- sa2sin(to)->sin_addr = *sin_addr;
- sa2sin(to)->sin_family = AF_INET;
- *tolen = sizeof(struct sockaddr_in);
+ to->sin_addr = *sin_addr;
+ to->sin_family = AF_INET;
return 1;
}
return 0;
#define check_cmsg_v6_pktinfo check_cmsg_ipv6_pktinfo
static int
-check_cmsg_ipv6_pktinfo(struct cmsghdr *cmsgptr, struct sockaddr *to,
- socklen_t *tolen, aux_addressing_info *auxaddr)
+check_cmsg_ipv6_pktinfo(struct cmsghdr *cmsgptr, struct sockaddr_in6 *to,
+ aux_addressing_info *auxaddr)
{
struct in6_pktinfo *pktinfo;
if (cmsgptr->cmsg_level == IPPROTO_IPV6 &&
- cmsgptr->cmsg_type == IPV6_PKTINFO &&
- *tolen >= sizeof(struct sockaddr_in6)) {
-
- memset(to, 0, sizeof(struct sockaddr_in6));
+ cmsgptr->cmsg_type == IPV6_PKTINFO) {
+ memset(to, 0, sizeof(*to));
pktinfo = cmsg2pktinfo6(cmsgptr);
- sa2sin6(to)->sin6_addr = pktinfo->ipi6_addr;
- sa2sin6(to)->sin6_family = AF_INET6;
- *tolen = sizeof(struct sockaddr_in6);
+ to->sin6_addr = pktinfo->ipi6_addr;
+ to->sin6_family = AF_INET6;
auxaddr->ipv6_ifindex = pktinfo->ipi6_ifindex;
return 1;
}
#endif /* HAVE_IPV6_PKTINFO */
static int
-check_cmsg_pktinfo(struct cmsghdr *cmsgptr, struct sockaddr *to,
- socklen_t *tolen, aux_addressing_info *auxaddr)
+check_cmsg_pktinfo(struct cmsghdr *cmsgptr, struct sockaddr_storage *to,
+ aux_addressing_info *auxaddr)
{
- return check_cmsg_v4_pktinfo(cmsgptr, to, tolen, auxaddr) ||
- check_cmsg_v6_pktinfo(cmsgptr, to, tolen, auxaddr);
+ return check_cmsg_v4_pktinfo(cmsgptr, ss2sin(to), auxaddr) ||
+ check_cmsg_v6_pktinfo(cmsgptr, ss2sin6(to), auxaddr);
}
/*
* len - buf length
* flags
* from - Set to the address that sent the message
- * fromlen
* to - Set to the address that the message was sent to if possible.
* May not be set in certain cases such as if pktinfo support is
* missing. May be NULL.
- * tolen
* auxaddr - Miscellaneous address information.
*
* Returns 0 on success, otherwise an error code.
*/
krb5_error_code
recv_from_to(int sock, void *buf, size_t len, int flags,
- struct sockaddr *from, socklen_t * fromlen,
- struct sockaddr *to, socklen_t * tolen,
+ struct sockaddr_storage *from, struct sockaddr_storage *to,
aux_addressing_info *auxaddr)
{
char cmsg[CMSG_SPACE(sizeof(union pktinfo))];
struct cmsghdr *cmsgptr;
struct msghdr msg;
+ socklen_t fromlen = sizeof(*from);
/* Don't use pktinfo if the socket isn't bound to a wildcard address. */
r = is_socket_bound_to_wildcard(sock);
if (r < 0)
return errno;
- if (!to || !tolen || !r)
- return recvfrom(sock, buf, len, flags, from, fromlen);
+ if (to == NULL || !r)
+ return recvfrom(sock, buf, len, flags, ss2sa(from), &fromlen);
/* Clobber with something recognizable in case we can't extract the address
* but try to use it anyways. */
- memset(to, 0x40, *tolen);
+ memset(to, 0x40, sizeof(*to));
+ to->ss_family = AF_UNSPEC;
iov.iov_base = buf;
iov.iov_len = len;
memset(&msg, 0, sizeof(msg));
- msg.msg_name = from;
- msg.msg_namelen = *fromlen;
+ msg.msg_name = ss2sa(from);
+ msg.msg_namelen = sizeof(*from);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = cmsg;
r = recvmsg(sock, &msg, flags);
if (r < 0)
return r;
- *fromlen = msg.msg_namelen;
/*
* On Darwin (and presumably all *BSD with KAME stacks), CMSG_FIRSTHDR
if (msg.msg_controllen) {
cmsgptr = CMSG_FIRSTHDR(&msg);
while (cmsgptr) {
- if (check_cmsg_pktinfo(cmsgptr, to, tolen, auxaddr))
+ if (check_cmsg_pktinfo(cmsgptr, to, auxaddr))
return r;
cmsgptr = CMSG_NXTHDR(&msg, cmsgptr);
}
}
/* No info about destination addr was available. */
- *tolen = 0;
return r;
}
#define set_msg_from_ipv4 set_msg_from_ip_pktinfo
static krb5_error_code
set_msg_from_ip_pktinfo(struct msghdr *msg, struct cmsghdr *cmsgptr,
- struct sockaddr *from, socklen_t fromlen,
+ const struct sockaddr_in *from,
aux_addressing_info *auxaddr)
{
struct in_pktinfo *p = cmsg2pktinfo(cmsgptr);
- const struct sockaddr_in *from4 = sa2sin(from);
- if (fromlen != sizeof(struct sockaddr_in))
- return EINVAL;
cmsgptr->cmsg_level = IPPROTO_IP;
cmsgptr->cmsg_type = IP_PKTINFO;
cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
- p->ipi_spec_dst = from4->sin_addr;
+ p->ipi_spec_dst = from->sin_addr;
msg->msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
return 0;
#define set_msg_from_ipv4 set_msg_from_ip_sendsrcaddr
static krb5_error_code
set_msg_from_ip_sendsrcaddr(struct msghdr *msg, struct cmsghdr *cmsgptr,
- struct sockaddr *from, socklen_t fromlen,
+ const struct sockaddr_in *from,
aux_addressing_info *auxaddr)
{
struct in_addr *sin_addr = cmsg2sin(cmsgptr);
- const struct sockaddr_in *from4 = sa2sin(from);
- if (fromlen != sizeof(struct sockaddr_in))
- return EINVAL;
+
cmsgptr->cmsg_level = IPPROTO_IP;
cmsgptr->cmsg_type = IP_SENDSRCADDR;
cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
msg->msg_controllen = CMSG_SPACE(sizeof(struct in_addr));
- *sin_addr = from4->sin_addr;
+ *sin_addr = from->sin_addr;
return 0;
}
#define set_msg_from_ipv6 set_msg_from_ipv6_pktinfo
static krb5_error_code
set_msg_from_ipv6_pktinfo(struct msghdr *msg, struct cmsghdr *cmsgptr,
- struct sockaddr *from, socklen_t fromlen,
+ const struct sockaddr_in6 *from,
aux_addressing_info *auxaddr)
{
struct in6_pktinfo *p = cmsg2pktinfo6(cmsgptr);
- const struct sockaddr_in6 *from6 = sa2sin6(from);
- if (fromlen != sizeof(struct sockaddr_in6))
- return EINVAL;
cmsgptr->cmsg_level = IPPROTO_IPV6;
cmsgptr->cmsg_type = IPV6_PKTINFO;
cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
- p->ipi6_addr = from6->sin6_addr;
+ p->ipi6_addr = from->sin6_addr;
/*
* Because of the possibility of asymmetric routing, we
* normally don't want to specify an interface. However,
* with a "foo.local" name) unless we do specify the
* interface.
*/
- if (IN6_IS_ADDR_LINKLOCAL(&from6->sin6_addr))
+ if (IN6_IS_ADDR_LINKLOCAL(&from->sin6_addr))
p->ipi6_ifindex = auxaddr->ipv6_ifindex;
/* otherwise, already zero */
#endif /* HAVE_IPV6_PKTINFO */
static krb5_error_code
-set_msg_from(int family, struct msghdr *msg, struct cmsghdr *cmsgptr,
- struct sockaddr *from, socklen_t fromlen,
- aux_addressing_info *auxaddr)
+set_msg_from(struct msghdr *msg, struct cmsghdr *cmsgptr,
+ const struct sockaddr *from, aux_addressing_info *auxaddr)
{
- switch (family) {
+ switch (from->sa_family) {
case AF_INET:
- return set_msg_from_ipv4(msg, cmsgptr, from, fromlen, auxaddr);
+ return set_msg_from_ipv4(msg, cmsgptr, sa2sin(from), auxaddr);
case AF_INET6:
- return set_msg_from_ipv6(msg, cmsgptr, from, fromlen, auxaddr);
+ return set_msg_from_ipv6(msg, cmsgptr, sa2sin6(from), auxaddr);
}
return EINVAL;
* len - buf length
* flags
* to - The address to send the message to.
- * tolen
* from - The address to attempt to send the message from. May be NULL.
- * fromlen
* auxaddr - Miscellaneous address information.
*
* Returns 0 on success, otherwise an error code.
*/
krb5_error_code
send_to_from(int sock, void *buf, size_t len, int flags,
- const struct sockaddr *to, socklen_t tolen, struct sockaddr *from,
- socklen_t fromlen, aux_addressing_info *auxaddr)
+ const struct sockaddr *to, const struct sockaddr *from,
+ aux_addressing_info *auxaddr)
{
int r;
struct iovec iov;
if (r < 0)
return errno;
- if (from == NULL || fromlen == 0 || from->sa_family != to->sa_family || !r)
+ if (from == NULL || from->sa_family != to->sa_family || !r)
goto use_sendto;
iov.iov_base = buf;
memset(cbuf, 0, sizeof(cbuf));
memset(&msg, 0, sizeof(msg));
msg.msg_name = (void *)to;
- msg.msg_namelen = tolen;
+ msg.msg_namelen = sa_socklen(to);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = cbuf;
cmsgptr = CMSG_FIRSTHDR(&msg);
msg.msg_controllen = 0;
- if (set_msg_from(from->sa_family, &msg, cmsgptr, from, fromlen, auxaddr))
+ if (set_msg_from(&msg, cmsgptr, from, auxaddr))
goto use_sendto;
return sendmsg(sock, &msg, flags);
use_sendto:
- return sendto(sock, buf, len, flags, to, tolen);
+ return sendto(sock, buf, len, flags, to, sa_socklen(to));
}
#else /* HAVE_PKTINFO_SUPPORT && CMSG_SPACE */
krb5_error_code
recv_from_to(int sock, void *buf, size_t len, int flags,
- struct sockaddr *from, socklen_t *fromlen,
- struct sockaddr *to, socklen_t *tolen,
+ struct sockaddr_storage *from, struct sockaddr_storage *to,
aux_addressing_info *auxaddr)
{
- if (to && tolen) {
+ socklen_t fromlen = sizeof(*from);
+
+ if (to != NULL) {
/* Clobber with something recognizable in case we try to use the
* address. */
- memset(to, 0x40, *tolen);
- *tolen = 0;
+ memset(to, 0x40, sizeof(*to));
+ to->ss_family = AF_UNSPEC;
}
- return recvfrom(sock, buf, len, flags, from, fromlen);
+ return recvfrom(sock, buf, len, flags, ss2sa(from), &fromlen);
}
krb5_error_code
send_to_from(int sock, void *buf, size_t len, int flags,
- const struct sockaddr *to, socklen_t tolen,
- struct sockaddr *from, socklen_t fromlen,
+ const struct sockaddr *to, const struct sockaddr *from,
aux_addressing_info *auxaddr)
{
- return sendto(sock, buf, len, flags, to, tolen);
+ return sendto(sock, buf, len, flags, to, sa_socklen(to));
}
#endif /* HAVE_PKTINFO_SUPPORT && CMSG_SPACE */