public void receive(DatagramPacket dp) throws IOException{
      super.receive(dp);

      if(server_mode){
        //Drop all datagrams not from relayIP/relayPort
         int init_length = dp.getLength();
         int initTimeout = getSoTimeout();
         long startTime = System.currentTimeMillis();

         while(!relayIP.equals(dp.getAddress()) ||
                relayPort != dp.getPort()){

           //Restore datagram size
           dp.setLength(init_length);

           //If there is a non-infinit timeout on this socket
           //Make sure that it happens no matter how often unexpected
           //packets arrive.
           if(initTimeout != 0){
             int newTimeout = initTimeout - (int)(System.currentTimeMillis() - 
                                                        startTime);
             if(newTimeout <= 0) throw new InterruptedIOException(
                                 "In Socks5DatagramSocket->receive()");
             setSoTimeout(newTimeout);
           }

           super.receive(dp);
         }

         //Restore timeout settings
         if(initTimeout != 0) setSoTimeout(initTimeout);

      }else if(!relayIP.equals(dp.getAddress()) ||
                relayPort != dp.getPort()) 
          return; // Recieved direct packet
      //If the datagram is not from the relay server, return it it as is.

      byte[] data;
      data = dp.getData();

      if(encapsulation != null)
         data = encapsulation.udpEncapsulate(data,false);

      int offset = 0; //Java 1.1
      //int offset = dp.getOffset(); //Java 1.2

      ByteArrayInputStream bIn = new ByteArrayInputStream(data,offset,
                                                              dp.getLength());


      ProxyMessage msg = new Socks5Message(bIn);
      dp.setPort(msg.port);
      dp.setAddress(msg.getInetAddress());

      //what wasn't read by the Message is the data
      int data_length = bIn.available();
      //Shift data to the left
      System.arraycopy(data,offset+dp.getLength()-data_length,
                       data,offset,data_length);


      dp.setLength(data_length);
   }