from configparser import ConfigParser
from logging import getLogger
from os import umask
-from socket import socket, AF_INET6, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
+from socket import (
+ socket,
+ AF_INET6,
+ SOCK_STREAM,
+ SOL_SOCKET,
+ SO_KEEPALIVE,
+ SO_REUSEADDR,
+)
from struct import pack
from time import time
from typing import Dict, List, Optional, Tuple
break
packet = self.buffer[2:frameend]
self.buffer = self.buffer[frameend + 2 :]
+ if len(packet) < 2: # frameend comes too early
+ log.warning("Packet too short: %s", packet)
+ break
if proto_of_message(packet) == LOGIN.PROTO:
- self.imei = parse_message(packet).imei
- log.info(
- "LOGIN from fd %d (IMEI %s)", self.sock.fileno(), self.imei
- )
+ msg = parse_message(packet)
+ if isinstance(msg, LOGIN): # Can be unparseable
+ self.imei = msg.imei
+ log.info(
+ "LOGIN from fd %d (IMEI %s)",
+ self.sock.fileno(),
+ self.imei,
+ )
msgs.append((when, self.addr, packet))
return msgs
except OSError as e:
log.error(
"Sending to fd %d (IMEI %s): %s",
- self.sock.fileno,
+ self.sock.fileno(),
self.imei,
e,
)
log.info("Not connected (IMEI %s)", resp.imei)
-def runserver(conf: ConfigParser) -> None:
+def runserver(conf: ConfigParser, handle_hibernate: bool = True) -> None:
# Is this https://github.com/zeromq/pyzmq/issues/1627 still not fixed?!
zctx = zmq.Context() # type: ignore
zpub = zctx.socket(zmq.PUB) # type: ignore
break
elif sk == tcpfd:
clntsock, clntaddr = tcpl.accept()
+ clntsock.setsockopt(SOL_SOCKET, SO_KEEPALIVE, 1)
topoll.append((clntsock, clntaddr))
elif fl & zmq.POLLIN:
received = clients.recv(sk)
packet=packet,
).packed
)
- if proto == HIBERNATION.PROTO:
+ if proto == HIBERNATION.PROTO and handle_hibernate:
log.debug(
"HIBERNATION from fd %d (IMEI %s)",
sk,
fd = clients.add(clntsock, clntaddr)
poller.register(fd, flags=zmq.POLLIN)
except KeyboardInterrupt:
- pass
+ zpub.close()
+ zpull.close()
+ zctx.destroy() # type: ignore
+ tcpl.close()
if __name__.endswith("__main__"):