return 0;
}
-static int addrAllowed(uint32_t addr)
+static int addrAllowed(struct sockaddr *saddr)
{
int i;
+ uint32_t addr;
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++)
{
if (addr == sockNetAddr[i]) return 1;
static void * pthSocketThread(void *x)
{
int fdC=0, c, *sock;
- struct sockaddr_in client;
+ struct sockaddr_storage client;
pthread_attr_t attr;
if (pthread_attr_init(&attr))
listen(fdSock, 100);
- c = sizeof(struct sockaddr_in);
+ c = sizeof(client);
/* don't start until DMA started */
closeOrphanedNotifications(-1, fdC);
- if (addrAllowed(client.sin_addr.s_addr))
+ if (addrAllowed((struct sockaddr *)&client))
{
sock = malloc(sizeof(int));
{
int rev, i, model;
struct sockaddr_in server;
+ struct sockaddr_in6 server6;
char * portStr;
unsigned port;
struct sched_param param;
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);
-
if (portStr) port = atoi(portStr); else port = gpioCfg.socketPort;
- server.sin_family = AF_INET;
- if (gpioCfg.ifFlags & PI_LOCALHOST_SOCK_IF)
+ // Accept connections on IPv6, unless we have an IPv4-only whitelist
+ if (!numSockNetAddr)
{
- server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ fdSock = socket(AF_INET6, SOCK_STREAM , 0);
+
+ if (fdSock != -1)
+ {
+ 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);
+ }
}
- else
+
+ if (numSockNetAddr || fdSock == -1)
{
- server.sin_addr.s_addr = htonl(INADDR_ANY);
- }
- server.sin_port = htons(port);
+ fdSock = socket(AF_INET , SOCK_STREAM , 0);
+
+ if (fdSock == -1)
+ SOFT_ERROR(PI_INIT_FAILED, "socket failed (%m)");
- if (bind(fdSock,(struct sockaddr *)&server , sizeof(server)) < 0)
- SOFT_ERROR(PI_INIT_FAILED, "bind to port %d failed (%m)", port);
+ 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))
SOFT_ERROR(PI_INIT_FAILED, "pthread_create socket failed (%m)");
self.event_bits = 0
self.callbacks = []
self.events = []
- self.sl.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.sl.s.settimeout(None)
- self.sl.s.connect((host, port))
+ self.sl.s = socket.create_connection((host, port), None)
self.handle = _pigpio_command(self.sl, _PI_CMD_NOIB, 0, 0)
self.go = True
self.start()
self._host = host
self._port = port
- self.sl.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.sl.s.settimeout(None)
+ try:
+ self.sl.s = socket.create_connection((host, port), None)
- # Disable the Nagle algorithm.
- self.sl.s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
+ # Disable the Nagle algorithm.
+ self.sl.s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
- try:
- self.sl.s.connect((host, port))
self._notify = _callback_thread(self.sl, host, port)
except socket.error: