Hello, I've found one bug which 'cashes' the whole server. I'm using Waterdog proxy, from which I normally redirect players to other servers (as usual), that works fine... But happend that the pocketmine server handled more packets than were allowed. So it blocked address 127.0.0.1 for 300 seconds. Also because of all the players log with ip 127.0.0.1 they weren't able to connect. Spoiler: receivePacket() function PHP: private function receivePacket() : bool{ $address = $this->reusableAddress; $len = $this->socket->readPacket($buffer, $address->ip, $address->port); if($len === false){ $error = $this->socket->getLastError(); if($error === SOCKET_EWOULDBLOCK){ //no data return false; }elseif($error === SOCKET_ECONNRESET){ //client disconnected improperly, maybe crash or lost connection return true; } $this->getLogger()->debug("Socket error occurred while trying to recv ($error): " . trim(socket_strerror($error))); return false; } $this->receiveBytes += $len; if(isset($this->block[$address->ip])){ return true; } if(isset($this->ipSec[$address->ip])){ if(++$this->ipSec[$address->ip] >= $this->packetLimit){ $this->blockAddress($address->ip); return true; } }else{ $this->ipSec[$address->ip] = 1; } if($len < 1){ return true; } try{ $pid = ord($buffer[0]); $session = $this->getSession($address); if($session !== null){ if(($pid & Datagram::BITFLAG_VALID) !== 0){ if($pid & Datagram::BITFLAG_ACK){ $session->handlePacket(new ACK($buffer)); }elseif($pid & Datagram::BITFLAG_NAK){ $session->handlePacket(new NACK($buffer)); }else{ $session->handlePacket(new Datagram($buffer)); } }else{ $this->server->getLogger()->debug("Ignored unconnected packet from $address due to session already opened (0x" . dechex($pid) . ")"); } }elseif(($pk = $this->getPacketFromPool($pid, $buffer)) instanceof OfflineMessage){ /** @var OfflineMessage $pk */ do{ try{ $pk->decode(); if(!$pk->isValid()){ throw new \InvalidArgumentException("Packet magic is invalid"); } }catch(\Throwable $e){ $logger = $this->server->getLogger(); $logger->debug("Received garbage message from $address (" . $e->getMessage() . "): " . bin2hex($pk->getBuffer())); foreach($this->server->getTrace(0, $e->getTrace()) as $line){ $logger->debug($line); } $this->blockAddress($address->ip, 5); break; } if(!$this->offlineMessageHandler->handle($pk, $address)){ $this->server->getLogger()->debug("Unhandled unconnected packet " . get_class($pk) . " received from $address"); } }while(false); }elseif(($pid & Datagram::BITFLAG_VALID) !== 0 and ($pid & 0x03) === 0){ // Loose datagram, don't relay it as a raw packet // RakNet does not currently use the 0x02 or 0x01 bitflags on any datagram header, so we can use // this to identify the difference between loose datagrams and packets like Query. $this->server->getLogger()->debug("Ignored connected packet from $address due to no session opened (0x" . dechex($pid) . ")"); }else{ $this->streamRaw($address, $buffer); } }catch(\Throwable $e){ $logger = $this->getLogger(); $logger->debug("Packet from $address (" . strlen($buffer) . " bytes): 0x" . bin2hex($buffer)); $logger->logException($e); $this->blockAddress($address->ip, 5); } return true;} Spoiler: blockAddress() function PHP: public function blockAddress(string $address, int $timeout = 300) : void{ $final = time() + $timeout; if(!isset($this->block[$address]) or $timeout === -1){ if($timeout === -1){ $final = PHP_INT_MAX; }else{ $this->getLogger()->notice("Blocked $address for $timeout seconds"); } $this->block[$address] = $final; }elseif($this->block[$address] < $final){ $this->block[$address] = $final; }} Is it possible to make blocking the adress depends also on port or completely disable this check?
Waterdog is a proxy software. If you connected to a server through proxy, your ip will the same as proxy's
This thread is about one months old, I'm pretty sure he fixed his problem. If not, ignore this post. it's commented out.