Add recvfromto6
This commit is contained in:
parent
c3eb1be0b4
commit
13d7080ac1
3 changed files with 78 additions and 24 deletions
4
l2tpns.c
4
l2tpns.c
|
|
@ -5205,14 +5205,14 @@ static void mainloop(void)
|
||||||
|
|
||||||
case FD_TYPE_CONTROL: // nsctl commands
|
case FD_TYPE_CONTROL: // nsctl commands
|
||||||
alen = sizeof(addr);
|
alen = sizeof(addr);
|
||||||
s = recvfromto(controlfd, p, size_bufp, MSG_WAITALL, (struct sockaddr *) &addr, &alen, &local);
|
s = recvfromto(controlfd, p, size_bufp, MSG_WAITALL, (struct sockaddr *) &addr, &alen, &local, NULL);
|
||||||
if (s > 0) processcontrol(p, s, &addr, alen, &local);
|
if (s > 0) processcontrol(p, s, &addr, alen, &local);
|
||||||
n--;
|
n--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FD_TYPE_DAE: // DAE requests
|
case FD_TYPE_DAE: // DAE requests
|
||||||
alen = sizeof(addr);
|
alen = sizeof(addr);
|
||||||
s = recvfromto(daefd, p, size_bufp, MSG_WAITALL, (struct sockaddr *) &addr, &alen, &local);
|
s = recvfromto(daefd, p, size_bufp, MSG_WAITALL, (struct sockaddr *) &addr, &alen, &local, NULL);
|
||||||
if (s > 0) processdae(p, s, &addr, alen, &local);
|
if (s > 0) processdae(p, s, &addr, alen, &local);
|
||||||
n--;
|
n--;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
93
util.c
93
util.c
|
|
@ -1,9 +1,11 @@
|
||||||
/* Misc util functions */
|
/* Misc util functions */
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/ip6.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -132,41 +134,90 @@ pid_t fork_and_close()
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t recvfromtox(int s, void *buf, size_t len, int flags,
|
||||||
|
struct sockaddr *from, socklen_t *fromlen, char *cbuf, size_t cbuflen, struct msghdr *msg)
|
||||||
|
{
|
||||||
|
ssize_t r;
|
||||||
|
struct iovec vec;
|
||||||
|
|
||||||
|
memset(msg, 0, sizeof(*msg));
|
||||||
|
msg->msg_name = from;
|
||||||
|
msg->msg_namelen = *fromlen;
|
||||||
|
|
||||||
|
vec.iov_base = buf;
|
||||||
|
vec.iov_len = len;
|
||||||
|
msg->msg_iov = &vec;
|
||||||
|
msg->msg_iovlen = 1;
|
||||||
|
msg->msg_flags = 0;
|
||||||
|
|
||||||
|
msg->msg_control = cbuf;
|
||||||
|
msg->msg_controllen = cbuflen;
|
||||||
|
|
||||||
|
if ((r = recvmsg(s, msg, flags)) < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (fromlen)
|
||||||
|
*fromlen = msg->msg_namelen;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t recvfromto(int s, void *buf, size_t len, int flags,
|
ssize_t recvfromto(int s, void *buf, size_t len, int flags,
|
||||||
struct sockaddr *from, socklen_t *fromlen, struct in_addr *toaddr)
|
struct sockaddr *from, socklen_t *fromlen, struct in_addr *toaddr, int *ifidx)
|
||||||
{
|
{
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct cmsghdr *cmsg;
|
struct cmsghdr *cmsg;
|
||||||
struct iovec vec;
|
char cbuf[BUFSIZ];
|
||||||
char cbuf[128];
|
|
||||||
|
|
||||||
memset(&msg, 0, sizeof(msg));
|
if ((r = recvfromtox(s, buf, len, flags, from, fromlen, cbuf, sizeof(cbuf), &msg)) < 0)
|
||||||
msg.msg_name = from;
|
|
||||||
msg.msg_namelen = *fromlen;
|
|
||||||
|
|
||||||
vec.iov_base = buf;
|
|
||||||
vec.iov_len = len;
|
|
||||||
msg.msg_iov = &vec;
|
|
||||||
msg.msg_iovlen = 1;
|
|
||||||
msg.msg_flags = 0;
|
|
||||||
|
|
||||||
msg.msg_control = cbuf;
|
|
||||||
msg.msg_controllen = sizeof(cbuf);
|
|
||||||
|
|
||||||
if ((r = recvmsg(s, &msg, flags)) < 0)
|
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (fromlen)
|
|
||||||
*fromlen = msg.msg_namelen;
|
|
||||||
|
|
||||||
memset(toaddr, 0, sizeof(*toaddr));
|
if (toaddr)
|
||||||
|
memset(toaddr, 0, sizeof(*toaddr));
|
||||||
|
if (ifidx)
|
||||||
|
*ifidx = -1;
|
||||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
|
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
|
||||||
{
|
{
|
||||||
if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_PKTINFO)
|
if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_PKTINFO)
|
||||||
{
|
{
|
||||||
struct in_pktinfo *i = (struct in_pktinfo *) CMSG_DATA(cmsg);
|
struct in_pktinfo *i = (struct in_pktinfo *) CMSG_DATA(cmsg);
|
||||||
memcpy(toaddr, &i->ipi_addr, sizeof(*toaddr));
|
if (toaddr)
|
||||||
|
memcpy(toaddr, &i->ipi_addr, sizeof(*toaddr));
|
||||||
|
if (ifidx)
|
||||||
|
*ifidx = i->ipi_ifindex;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t recvfromto6(int s, void *buf, size_t len, int flags,
|
||||||
|
struct sockaddr *from, socklen_t *fromlen, struct in6_addr *toaddr, int *ifidx)
|
||||||
|
{
|
||||||
|
ssize_t r;
|
||||||
|
struct msghdr msg;
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
|
char cbuf[BUFSIZ];
|
||||||
|
|
||||||
|
if ((r = recvfromtox(s, buf, len, flags, from, fromlen, cbuf, sizeof(cbuf), &msg)) < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (toaddr)
|
||||||
|
memset(toaddr, 0, sizeof(*toaddr));
|
||||||
|
if (ifidx)
|
||||||
|
*ifidx = -1;
|
||||||
|
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
|
||||||
|
{
|
||||||
|
if (cmsg->cmsg_level == SOL_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO)
|
||||||
|
{
|
||||||
|
struct in6_pktinfo *i = (struct in6_pktinfo *) CMSG_DATA(cmsg);
|
||||||
|
if (toaddr)
|
||||||
|
memcpy(toaddr, &i->ipi6_addr, sizeof(*toaddr));
|
||||||
|
if (ifidx)
|
||||||
|
*ifidx = i->ipi6_ifindex;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
5
util.h
5
util.h
|
|
@ -10,6 +10,9 @@ ssize_t sendtofrom(int s, void const *buf, size_t len, int flags,
|
||||||
struct sockaddr const *to, socklen_t tolen, struct in_addr const *from);
|
struct sockaddr const *to, socklen_t tolen, struct in_addr const *from);
|
||||||
|
|
||||||
ssize_t recvfromto(int s, void *buf, size_t len, int flags,
|
ssize_t recvfromto(int s, void *buf, size_t len, int flags,
|
||||||
struct sockaddr *from, socklen_t *fromlen, struct in_addr *toaddr);
|
struct sockaddr *from, socklen_t *fromlen, struct in_addr *toaddr, int *ifidx);
|
||||||
|
|
||||||
|
ssize_t recvfromto6(int s, void *buf, size_t len, int flags,
|
||||||
|
struct sockaddr *from, socklen_t *fromlen, struct in6_addr *toaddr, int *ifidx);
|
||||||
|
|
||||||
#endif /* __UTIL_H__ */
|
#endif /* __UTIL_H__ */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue