Hi,

I'm using JSch in a system that uses lots of connections to a SFTP server to transfer large amounts of data. This worked well with Java 6, but occasionally SSH connect fails with "verify: false" on Java 7. The problem looks very much like the bug described in the release notes of version 0.1.50:

Changes since version 0.1.49:
- bugfix: "verify: false" error on Java7u6(and later).  FIXED.
http://stackoverflow.com/questions/12279836/ssh-using-jschexception-verify-false-sometimes-fails
https://issues.apache.org/jira/browse/IVY-1374

Here's the stack trace I get:

com.jcraft.jsch.JSchException: verify: false
        at com.jcraft.jsch.Session.connect(Session.java:330)
        at com.jcraft.jsch.Session.connect(Session.java:183)

I still see this problem with Java 1.7.0u21 and JSch 0.1.50. The attached unit test connects to an OpenSSH server 1,000,000 times using 20 threads. In 500,000 connects I see about two or three attempts that fail with the error described above. I ran the test several times and the error usually first shows up after about 250,000 connections.

To find a work-around I changed some of the JSch configuration parameters that seem to be relevant for the key exchange --- without success. These configurations didn't work around the problem:

- turning compression off
- setting "kex" to "diffie-hellman-group-exchange-sha256"
- setting "kex" to "diffie-hellman-group-exchange-sha1"
- setting "kex" to "diffie-hellman-group1-sha1"

Is there something else I can try? Do you have any advice on debugging the problem?

Best regards,

Eric
import static java.text.MessageFormat.format;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import org.junit.Test;

public class JSchTest {

    private static final String USER = "sftparc";
    private static final String HOST = "localhost";
    private static final int PORT = 10022;

    private static final String HOST_KEY =
        "localhost ssh-rsa 
AAAAB3NzaC1yc2EAAAABIwAAAQEAwpnB0iqtlvPcIJUh8EL+N7PJhn+il5Xe/PlbF6uPxu8dVRP3rQ/14M6NVGxm7IeEaCDofaqJkQsRHJkakDVhD1JJsqniykDBRCTUczcLLZ15z7CkIY/Dyt1WmfnFXh/gUcifShADYHukRucvy33gP2zMt8JYTGnWO3/i1dMwazEutbPygrdKi27yy67e50dfUlLy1Jfu+d8lCSf8fV+D3o8r9z89X7suP0481fMXjGSWZXeGohZ1WBxMK6dRFXqc0p/QQS9kHIz5Ted0Tu2dDLrs95Nv31XRmVKRnSBvJ2Ae7WCcr4cDzwSA6pQwQU1AWpQDC8J43o2SdalQak7zLQ==\n"
 +
        "[localhost]:10022 ssh-rsa 
AAAAB3NzaC1yc2EAAAABIwAAAQEAwpnB0iqtlvPcIJUh8EL+N7PJhn+il5Xe/PlbF6uPxu8dVRP3rQ/14M6NVGxm7IeEaCDofaqJkQsRHJkakDVhD1JJsqniykDBRCTUczcLLZ15z7CkIY/Dyt1WmfnFXh/gUcifShADYHukRucvy33gP2zMt8JYTGnWO3/i1dMwazEutbPygrdKi27yy67e50dfUlLy1Jfu+d8lCSf8fV+D3o8r9z89X7suP0481fMXjGSWZXeGohZ1WBxMK6dRFXqc0p/QQS9kHIz5Ted0Tu2dDLrs95Nv31XRmVKRnSBvJ2Ae7WCcr4cDzwSA6pQwQU1AWpQDC8J43o2SdalQak7zLQ==\n";

    private static final AtomicInteger count = new AtomicInteger(0);
    private static final AtomicInteger failCount = new AtomicInteger(0);
    private static final AtomicInteger okCount = new AtomicInteger(0);

    private static class ProgessThread implements Runnable {

        private final int totalCount;
        private final int delay = 5000;

        private ProgessThread(int totalCount) {

            this.totalCount = totalCount;
        }

        @Override
        public void run() {

            try {
                System.out.println(
                    format("testing {0} times", totalCount));

                int i = 0;
                while (count.get() < totalCount) {
                    int j = count.get();
                    float rate = (j - i) / (delay / 1000);
                    i = j;
                    System.out.println(
                        format("i={0}, ok={1}, fail={2}, current rate: {3} 
connects/sec",
                            count.get(), okCount.get(), failCount.get(), rate));
                    Thread.sleep(delay);
                }
            } catch (InterruptedException e) {
               // do nothing
            }
        }
    }

    private static class RunConnect implements Runnable {

        private final int numLoops;

        private RunConnect(int numLoops) {
            this.numLoops = numLoops;
        }

        @Override
        public void run() {

            JSch jsch = new JSch();
            try {
                jsch.setKnownHosts(new 
ByteArrayInputStream(HOST_KEY.getBytes()));
            } catch (JSchException e) {
                throw new IllegalStateException(e);
            }

            for (int i = 0; i < numLoops; i++) {
                count.incrementAndGet();
                try {
                    Session session = jsch.getSession(USER, HOST, PORT);
                    session.setPassword("sftparc");
                    session.connect();

                    //System.out.println(session.getConfig("kex"));
                    session.disconnect();
                    okCount.incrementAndGet();
                } catch (JSchException ex) {
                    ex.printStackTrace();
                    failCount.incrementAndGet();
                }
            }
        }
    }

    @Test
    public void testConnectParallel() throws Exception {

        int loopsPerThread = 50000;
        int numThreads = 20;

        count.set(0);
        failCount.set(0);
        okCount.set(0);

        List<Thread> threads = new ArrayList<Thread>();

        Thread pt = new Thread(new ProgessThread(numThreads * loopsPerThread));
        threads.add(pt);
        pt.start();

        for (int i = 0; i < numThreads; i++) {
            Thread t = new Thread(new RunConnect(loopsPerThread));
            threads.add(t);
            t.start();
        }

        for (Thread t : threads) {
            t.join();
        }

        System.out.println(
            format("finalResult: i={0}, ok={1}, fail={2}",
                count.get(), okCount.get(), failCount.get()));

    }
}
------------------------------------------------------------------------------
How ServiceNow helps IT people transform IT departments:
1. A cloud service to automate IT design, transition and operations
2. Dashboards that offer high-level views of enterprise services
3. A single system of record for all IT processes
http://p.sf.net/sfu/servicenow-d2d-j
_______________________________________________
JSch-users mailing list
JSch-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jsch-users

Reply via email to