41 private array $interfaces = [];
44 private array $advancedInterfaces = [];
47 private array $rawPacketHandlers = [];
53 private array $bannedIps = [];
59 public function __construct(
72 return $this->interfaces;
76 return $this->sessionManager;
79 public function getConnectionCount() : int{
80 return $this->sessionManager->getSessionCount();
83 public function getValidConnectionCount() : int{
84 return $this->sessionManager->getValidSessionCount();
87 public function tick() : void{
88 foreach($this->interfaces as $interface){
92 $this->sessionManager->tick();
101 if(!$ev->isCancelled()){
103 $this->interfaces[$hash = spl_object_id($interface)] = $interface;
104 if($interface instanceof AdvancedNetworkInterface){
105 $this->advancedInterfaces[$hash] = $interface;
106 $interface->setNetwork($this);
107 foreach(Utils::stringifyKeys($this->bannedIps) as $ip => $until){
108 $interface->blockAddress($ip);
110 foreach($this->rawPacketHandlers as $handler){
111 $interface->addRawPacketFilter($handler->getPattern());
114 $interface->setName($this->name);
124 if(!isset($this->interfaces[$hash = spl_object_id($interface)])){
125 throw new \InvalidArgumentException(
"Interface " . get_class($interface) .
" is not registered on this network");
128 unset($this->interfaces[$hash], $this->advancedInterfaces[$hash]);
137 foreach($this->interfaces as $interface){
138 $interface->setName($this->name);
142 public function getName() : string{
146 public function updateName() : void{
147 foreach($this->interfaces as $interface){
148 $interface->setName($this->name);
152 public function sendPacket(
string $address,
int $port,
string $payload) : void{
153 foreach($this->advancedInterfaces as $interface){
154 $interface->sendRawPacket($address, $port, $payload);
161 public function blockAddress(
string $address,
int $timeout = 300) : void{
162 $this->bannedIps[$address] = $timeout > 0 ? time() + $timeout : PHP_INT_MAX;
163 foreach($this->advancedInterfaces as $interface){
164 $interface->blockAddress($address, $timeout);
168 public function unblockAddress(
string $address) : void{
169 unset($this->bannedIps[$address]);
170 foreach($this->advancedInterfaces as $interface){
171 $interface->unblockAddress($address);
179 $this->rawPacketHandlers[spl_object_id($handler)] = $handler;
182 foreach($this->advancedInterfaces as $interface){
183 $interface->addRawPacketFilter($regex);
191 unset($this->rawPacketHandlers[spl_object_id($handler)]);
194 public function processRawPacket(
AdvancedNetworkInterface $interface,
string $address,
int $port,
string $packet) : void{
195 if(isset($this->bannedIps[$address]) && time() < $this->bannedIps[$address]){
196 $this->logger->debug(
"Dropped raw packet from banned address $address $port");
200 foreach($this->rawPacketHandlers as $handler){
201 if(preg_match($handler->getPattern(), $packet) === 1){
203 $handled = $handler->handle($interface, $address, $port, $packet);
204 }
catch(PacketHandlingException $e){
206 $this->logger->error(
"Bad raw packet from /$address:$port: " . $e->getMessage());
207 $this->blockAddress($address, 600);
213 $this->logger->debug(
"Unhandled raw packet from /$address:$port: " . base64_encode($packet));