mirror of https://github.com/joan2937/pigpio
Add basic IPv6 support
Add IPv6 support to daemon and python library. IPv6 was already supported by the C client library. Currently there is no support for whitelisting IPv6 client addresses implemented, so for now it reverts to listening to IPv4 only when the -n <ip> option is specified. Signed-off-by: Floris Bos <bos@je-eigen-domein.nl>
This commit is contained in:
parent
03a7255fad
commit
7eec4b6c88
75
pigpio.c
75
pigpio.c
|
@ -6972,12 +6972,18 @@ static void *pthSocketThreadHandler(void *fdC)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int addrAllowed(uint32_t addr)
|
static int addrAllowed(struct sockaddr *saddr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
uint32_t addr;
|
||||||
|
|
||||||
if (!numSockNetAddr) return 1;
|
if (!numSockNetAddr) return 1;
|
||||||
|
|
||||||
|
// FIXME: add IPv6 whitelisting support
|
||||||
|
if (saddr->sa_family != AF_INET) return 0;
|
||||||
|
|
||||||
|
addr = ((struct sockaddr_in *) saddr)->sin_addr.s_addr;
|
||||||
|
|
||||||
for (i=0; i<numSockNetAddr; i++)
|
for (i=0; i<numSockNetAddr; i++)
|
||||||
{
|
{
|
||||||
if (addr == sockNetAddr[i]) return 1;
|
if (addr == sockNetAddr[i]) return 1;
|
||||||
|
@ -6990,7 +6996,7 @@ static int addrAllowed(uint32_t addr)
|
||||||
static void * pthSocketThread(void *x)
|
static void * pthSocketThread(void *x)
|
||||||
{
|
{
|
||||||
int fdC=0, c, *sock;
|
int fdC=0, c, *sock;
|
||||||
struct sockaddr_in client;
|
struct sockaddr_storage client;
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
|
|
||||||
if (pthread_attr_init(&attr))
|
if (pthread_attr_init(&attr))
|
||||||
|
@ -7010,7 +7016,7 @@ static void * pthSocketThread(void *x)
|
||||||
|
|
||||||
listen(fdSock, 100);
|
listen(fdSock, 100);
|
||||||
|
|
||||||
c = sizeof(struct sockaddr_in);
|
c = sizeof(client);
|
||||||
|
|
||||||
/* don't start until DMA started */
|
/* don't start until DMA started */
|
||||||
|
|
||||||
|
@ -7024,7 +7030,7 @@ static void * pthSocketThread(void *x)
|
||||||
|
|
||||||
closeOrphanedNotifications(-1, fdC);
|
closeOrphanedNotifications(-1, fdC);
|
||||||
|
|
||||||
if (addrAllowed(client.sin_addr.s_addr))
|
if (addrAllowed((struct sockaddr *)&client))
|
||||||
{
|
{
|
||||||
sock = malloc(sizeof(int));
|
sock = malloc(sizeof(int));
|
||||||
|
|
||||||
|
@ -8003,6 +8009,7 @@ int initInitialise(void)
|
||||||
{
|
{
|
||||||
int rev, i, model;
|
int rev, i, model;
|
||||||
struct sockaddr_in server;
|
struct sockaddr_in server;
|
||||||
|
struct sockaddr_in6 server6;
|
||||||
char * portStr;
|
char * portStr;
|
||||||
unsigned port;
|
unsigned port;
|
||||||
struct sched_param param;
|
struct sched_param param;
|
||||||
|
@ -8107,28 +8114,54 @@ int initInitialise(void)
|
||||||
|
|
||||||
if (!(gpioCfg.ifFlags & PI_DISABLE_SOCK_IF))
|
if (!(gpioCfg.ifFlags & PI_DISABLE_SOCK_IF))
|
||||||
{
|
{
|
||||||
fdSock = socket(AF_INET , SOCK_STREAM , 0);
|
|
||||||
|
|
||||||
if (fdSock == -1)
|
|
||||||
SOFT_ERROR(PI_INIT_FAILED, "socket failed (%m)");
|
|
||||||
|
|
||||||
portStr = getenv(PI_ENVPORT);
|
portStr = getenv(PI_ENVPORT);
|
||||||
|
|
||||||
if (portStr) port = atoi(portStr); else port = gpioCfg.socketPort;
|
if (portStr) port = atoi(portStr); else port = gpioCfg.socketPort;
|
||||||
|
|
||||||
server.sin_family = AF_INET;
|
// Accept connections on IPv6, unless we have an IPv4-only whitelist
|
||||||
if (gpioCfg.ifFlags & PI_LOCALHOST_SOCK_IF)
|
if (!numSockNetAddr)
|
||||||
{
|
{
|
||||||
server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
fdSock = socket(AF_INET6, SOCK_STREAM , 0);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
server.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
}
|
|
||||||
server.sin_port = htons(port);
|
|
||||||
|
|
||||||
if (bind(fdSock,(struct sockaddr *)&server , sizeof(server)) < 0)
|
if (fdSock != -1)
|
||||||
SOFT_ERROR(PI_INIT_FAILED, "bind to port %d failed (%m)", port);
|
{
|
||||||
|
bzero((char *)&server6, sizeof(server6));
|
||||||
|
server6.sin6_family = AF_INET6;
|
||||||
|
if (gpioCfg.ifFlags & PI_LOCALHOST_SOCK_IF)
|
||||||
|
{
|
||||||
|
server6.sin6_addr = in6addr_loopback;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
server6.sin6_addr = in6addr_any;
|
||||||
|
}
|
||||||
|
server6.sin6_port = htons(port);
|
||||||
|
|
||||||
|
if (bind(fdSock,(struct sockaddr *)&server6, sizeof(server6)) < 0)
|
||||||
|
SOFT_ERROR(PI_INIT_FAILED, "bind to port %d failed (%m)", port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numSockNetAddr || fdSock == -1)
|
||||||
|
{
|
||||||
|
fdSock = socket(AF_INET , SOCK_STREAM , 0);
|
||||||
|
|
||||||
|
if (fdSock == -1)
|
||||||
|
SOFT_ERROR(PI_INIT_FAILED, "socket failed (%m)");
|
||||||
|
|
||||||
|
server.sin_family = AF_INET;
|
||||||
|
if (gpioCfg.ifFlags & PI_LOCALHOST_SOCK_IF)
|
||||||
|
{
|
||||||
|
server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
server.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
}
|
||||||
|
server.sin_port = htons(port);
|
||||||
|
|
||||||
|
if (bind(fdSock,(struct sockaddr *)&server , sizeof(server)) < 0)
|
||||||
|
SOFT_ERROR(PI_INIT_FAILED, "bind to port %d failed (%m)", port);
|
||||||
|
}
|
||||||
|
|
||||||
if (pthread_create(&pthSocket, &pthAttr, pthSocketThread, &i))
|
if (pthread_create(&pthSocket, &pthAttr, pthSocketThread, &i))
|
||||||
SOFT_ERROR(PI_INIT_FAILED, "pthread_create socket failed (%m)");
|
SOFT_ERROR(PI_INIT_FAILED, "pthread_create socket failed (%m)");
|
||||||
|
|
16
pigpio.py
16
pigpio.py
|
@ -1047,9 +1047,7 @@ class _callback_thread(threading.Thread):
|
||||||
self.event_bits = 0
|
self.event_bits = 0
|
||||||
self.callbacks = []
|
self.callbacks = []
|
||||||
self.events = []
|
self.events = []
|
||||||
self.sl.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
self.sl.s = socket.create_connection((host, port), None)
|
||||||
self.sl.s.settimeout(None)
|
|
||||||
self.sl.s.connect((host, port))
|
|
||||||
self.handle = _pigpio_command(self.sl, _PI_CMD_NOIB, 0, 0)
|
self.handle = _pigpio_command(self.sl, _PI_CMD_NOIB, 0, 0)
|
||||||
self.go = True
|
self.go = True
|
||||||
self.start()
|
self.start()
|
||||||
|
@ -4931,14 +4929,12 @@ class pi():
|
||||||
self._host = host
|
self._host = host
|
||||||
self._port = port
|
self._port = port
|
||||||
|
|
||||||
self.sl.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
self.sl.s.settimeout(None)
|
|
||||||
|
|
||||||
# Disable the Nagle algorithm.
|
|
||||||
self.sl.s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.sl.s.connect((host, port))
|
self.sl.s = socket.create_connection((host, port), None)
|
||||||
|
|
||||||
|
# Disable the Nagle algorithm.
|
||||||
|
self.sl.s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||||
|
|
||||||
self._notify = _callback_thread(self.sl, host, port)
|
self._notify = _callback_thread(self.sl, host, port)
|
||||||
|
|
||||||
except socket.error:
|
except socket.error:
|
||||||
|
|
Loading…
Reference in New Issue