[jcifs] Endless loop while contacting WINS if none of the servers

Dominique Laurent lauredo at gmail.com
Mon Oct 30 16:01:44 GMT 2006


Hello Stefan,

We observed the same behaviour. Actually it caused a Denial of
Services on our production servers, because we had two WINS servers
configured and they were not available at that time => all threads
became endlessly looping => no more thread and file handles available
=> DoS

Could one of the jcifs committers add the patch into the repository?

Also there seems to be something strange in the condition
NbtAddress.isWINS( request.addr ) which in the loop is always true
unless NBNS is empty.

Thanks in advance,
Dominique.

P.S. Hereunder is a slightly modified version of the method (same
logic but less lines):


    void send( NameServicePacket request, NameServicePacket response,
               int timeout ) throws IOException {
        Integer nid = null;
        int count = NbtAddress.NBNS.length;

        synchronized( response ) {
            do {
                try {
                    synchronized( LOCK ) {
                        request.nameTrnId = getNextNameTrnId();
                        nid = new Integer( request.nameTrnId );

                        out.setAddress( request.addr );
                        out.setLength( request.writeWireFormat( snd_buf, 0 ));
                        response.received = false;

                        responseTable.put( nid, response );
                        ensureOpen( timeout + 1000 );
                        socket.send( out );

                        if( log.level > 3 ) {
                            log.println( request );
                            Hexdump.hexdump( log, snd_buf, 0, out.getLength() );
                        }
                    }

                    response.wait( timeout );

                } catch( InterruptedException ie ) {
                } finally {
                    responseTable.remove( nid );
                }
                if( !response.received &&
                        --count > 0 &&
                        NbtAddress.isWINS( request.addr )) {
                    /* Message was sent to WINS but
                    * failed to receive response.
                    * Try a different WINS server.
                    */
                    request.addr = NbtAddress.switchWINS();
                } else {
                    break;
                }
            } while( true );
        }
    }





-------------------------------------------------
> Hi,
>
> we configured two WINS servers for jcifs (version 1.2.9) HTTP NTLM authentication. We discovered that jcifs hangs in an endless loop if none of the servers is reachable, i.e. the IP-addresses point to non-existing servers.
> I supposed that jcifs would return an error or throw an exception after the configured timeout, but apparently it didn't return at all.
>
> So I investigated the code and I found a problem in the class    jcifs.netbios.NameServiceClient .
> In method
>   void send( NameServicePacket request, NameServicePacket response, int timeout)
> the loop trying all WINS servers is not correctly terminated. It tries the first server, then the second and then (in case you configured two servers) first again and so on. So as long > as none of the servers gives an answer the method will not be left although the timeouts occur. I suppose that is not desired.
>
> I fixed it in our local copy of jcifs and I would appreciate if someone could tell me if I misunderstood something.
> You will find my version of the method later on.
>
> Thx for your help,
> Stefan
>
> ----
>     void send( NameServicePacket request, NameServicePacket response,
>                                             int timeout ) throws IOException {
>         Integer nid = null;
>         int count = NbtAddress.NBNS.length;
>
>         synchronized( response ) {
>             do {
>                 try {
>                     synchronized( LOCK ) {
>                         request.nameTrnId = getNextNameTrnId();
>                         nid = new Integer( request.nameTrnId );
>
>                         out.setAddress( request.addr );
>                         out.setLength( request.writeWireFormat( snd_buf, 0 ));
>                         response.received = false;
>
>                         responseTable.put( nid, response );
>                         ensureOpen( timeout + 1000 );
>                         socket.send( out );
>
>                         if( log.level > 3 ) {
>                             log.println( request );
>                             Hexdump.hexdump( log, snd_buf, 0, out.getLength() );
>                         }
>                     }
>
>                     response.wait( timeout );
>
>                 } catch( InterruptedException ie ) {
>                 } finally {
>                     responseTable.remove( nid );
>                 }
>
>                 if( !response.received &&
>                             NbtAddress.NBNS.length > 1 &&
>                             NbtAddress.isWINS( request.addr )) {
>                                 /* Message was sent to WINS but
>                                  * failed to receive response.
>                                  * Try a different WINS server.
>                                  */
>                     count--;
>                     if (count > 0) {
>                       request.addr = NbtAddress.switchWINS();
>                     } else {
>                       break;
>                     }
>                 } else {
>                   break;
>                 }
>             } while( true );
>         }
>     }


More information about the jcifs mailing list