Example #1
0
static jdwpTransportError
handshake(int fd, jlong timeout) {
    const char *hello = "JDWP-Handshake";
    char b[16];
    int rv, helloLen, received;

    if (timeout > 0) {
        dbgsysConfigureBlocking(fd, JNI_FALSE);
    }
    helloLen = (int)strlen(hello);
    received = 0;
    while (received < helloLen) {
        int n;
        char *buf;
        if (timeout > 0) {
            rv = dbgsysPoll(fd, JNI_TRUE, JNI_FALSE, (long)timeout);
            if (rv <= 0) {
                setLastError(0, "timeout during handshake");
                return JDWPTRANSPORT_ERROR_IO_ERROR;
            }
        }
        buf = b;
        buf += received;
        n = recv_fully(fd, buf, helloLen-received);
        if (n == 0) {
            setLastError(0, "handshake failed - connection prematurally closed");
            return JDWPTRANSPORT_ERROR_IO_ERROR;
        }
        if (n < 0) {
            RETURN_IO_ERROR("recv failed during handshake");
        }
        received += n;
    }
    if (timeout > 0) {
        dbgsysConfigureBlocking(fd, JNI_TRUE);
    }
    if (strncmp(b, hello, received) != 0) {
        char msg[80+2*16];
        b[received] = '\0';
        /*
         * We should really use snprintf here but it's not available on Windows.
         * We can't use jio_snprintf without linking the transport against the VM.
         */
        sprintf(msg, "handshake failed - received >%s< - expected >%s<", b, hello);
        setLastError(0, msg);
        return JDWPTRANSPORT_ERROR_IO_ERROR;
    }

    if (send_fully(fd, (char*)hello, helloLen) != helloLen) {
        RETURN_IO_ERROR("send failed during handshake");
    }
    return JDWPTRANSPORT_ERROR_NONE;
}
static jdwpTransportError
handshake(int fd, jlong timeout) {
    char *hello = "JDWP-Handshake";
    char b[16];
    int rv, received, i;

    if (timeout > 0) {
        dbgsysConfigureBlocking(fd, JNI_FALSE);
    }
    received = 0;
    while (received < (int)strlen(hello)) {
        int n;
        char *buf;
        if (timeout > 0) {
            rv = dbgsysPoll(fd, JNI_TRUE, JNI_FALSE, (long)timeout);
            if (rv <= 0) {
                setLastError(0, "timeout during handshake");
                return JDWPTRANSPORT_ERROR_IO_ERROR;
            }
        }
        buf = b;
        buf += received;
        n = dbgsysRecv(fd, buf, strlen(hello)-received, 0);
        if (n == 0) {
            setLastError(0, "handshake failed - connection prematurally closed");
            return JDWPTRANSPORT_ERROR_IO_ERROR;
        }
        if (n < 0) {
            RETURN_IO_ERROR("recv failed during handshake");
        }
        received += n;
    }
    if (timeout > 0) {
        dbgsysConfigureBlocking(fd, JNI_TRUE);
    }
    for (i=0; i<(int)strlen(hello); i++) {
        if (b[i] != hello[i]) {
            char msg[64];
            strcpy(msg, "handshake failed - received >");
            strncat(msg, b, strlen(hello));
            strcat(msg, "< - excepted >");
            strcat(msg, hello);
            strcat(msg, "<");
            setLastError(0, msg);
            return JDWPTRANSPORT_ERROR_IO_ERROR;
        }
    }

    if (dbgsysSend(fd, hello, strlen(hello), 0) != (int)strlen(hello)) {
        RETURN_IO_ERROR("send failed during handshake");
    }
    return JDWPTRANSPORT_ERROR_NONE;
}
Example #3
0
static jdwpTransportError JNICALL
socketTransport_attach(jdwpTransportEnv* env, const char* addressString, jlong attachTimeout,
                       jlong handshakeTimeout)
{
    struct sockaddr_in sa;
    int err;

    if (addressString == NULL || addressString[0] == '\0') {
        RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "address is missing");
    }

    err = parseAddress(addressString, &sa, 0x7f000001);
    if (err != JDWPTRANSPORT_ERROR_NONE) {
        return err;
    }

    socketFD = dbgsysSocket(AF_INET, SOCK_STREAM, 0);
    if (socketFD < 0) {
        RETURN_IO_ERROR("unable to create socket");
    }

    err = setOptions(socketFD);
    if (err) {
        return err;
    }

    /*
     * To do a timed connect we make the socket non-blocking
     * and poll with a timeout;
     */
    if (attachTimeout > 0) {
        dbgsysConfigureBlocking(socketFD, JNI_FALSE);
    }

    err = dbgsysConnect(socketFD, (struct sockaddr *)&sa, sizeof(sa));
    if (err == DBG_EINPROGRESS && attachTimeout > 0) {
        err = dbgsysFinishConnect(socketFD, (long)attachTimeout);

        if (err == DBG_ETIMEOUT) {
            dbgsysConfigureBlocking(socketFD, JNI_TRUE);
            RETURN_ERROR(JDWPTRANSPORT_ERROR_TIMEOUT, "connect timed out");
        }
    }

    if (err < 0) {
        RETURN_IO_ERROR("connect failed");
    }

    if (attachTimeout > 0) {
        dbgsysConfigureBlocking(socketFD, JNI_TRUE);
    }

    err = handshake(socketFD, handshakeTimeout);
    if (err) {
        dbgsysSocketClose(socketFD);
        socketFD = -1;
        return err;
    }

    return JDWPTRANSPORT_ERROR_NONE;
}
Example #4
0
static jdwpTransportError JNICALL
socketTransport_accept(jdwpTransportEnv* env, jlong acceptTimeout, jlong handshakeTimeout)
{
    int socketLen, err;
    struct sockaddr_in socket;
    jlong startTime = (jlong)0;

    /*
     * Use a default handshake timeout if not specified - this avoids an indefinite
     * hang in cases where something other than a debugger connects to our port.
     */
    if (handshakeTimeout == 0) {
        handshakeTimeout = 2000;
    }

    do {
        /*
         * If there is an accept timeout then we put the socket in non-blocking
         * mode and poll for a connection.
         */
        if (acceptTimeout > 0) {
            int rv;
            dbgsysConfigureBlocking(serverSocketFD, JNI_FALSE);
            startTime = dbgsysCurrentTimeMillis();
            rv = dbgsysPoll(serverSocketFD, JNI_TRUE, JNI_FALSE, (long)acceptTimeout);
            if (rv <= 0) {
                /* set the last error here as could be overridden by configureBlocking */
                if (rv == 0) {
                    setLastError(JDWPTRANSPORT_ERROR_IO_ERROR, "poll failed");
                }
                /* restore blocking state */
                dbgsysConfigureBlocking(serverSocketFD, JNI_TRUE);
                if (rv == 0) {
                    RETURN_ERROR(JDWPTRANSPORT_ERROR_TIMEOUT, "timed out waiting for connection");
                } else {
                    return JDWPTRANSPORT_ERROR_IO_ERROR;
                }
            }
        }

        /*
         * Accept the connection
         */
        memset((void *)&socket,0,sizeof(struct sockaddr_in));
        socketLen = sizeof(socket);
        socketFD = dbgsysAccept(serverSocketFD,
                                (struct sockaddr *)&socket,
                                &socketLen);
        /* set the last error here as could be overridden by configureBlocking */
        if (socketFD < 0) {
            setLastError(JDWPTRANSPORT_ERROR_IO_ERROR, "accept failed");
        }
        /*
         * Restore the blocking state - note that the accepted socket may be in
         * blocking or non-blocking mode (platform dependent). However as there
         * is a handshake timeout set then it will go into non-blocking mode
         * anyway for the handshake.
         */
        if (acceptTimeout > 0) {
            dbgsysConfigureBlocking(serverSocketFD, JNI_TRUE);
        }
        if (socketFD < 0) {
            return JDWPTRANSPORT_ERROR_IO_ERROR;
        }

        /* handshake with the debugger */
        err = handshake(socketFD, handshakeTimeout);

        /*
         * If the handshake fails then close the connection. If there if an accept
         * timeout then we must adjust the timeout for the next poll.
         */
        if (err) {
            fprintf(stderr, "Debugger failed to attach: %s\n", getLastError());
            dbgsysSocketClose(socketFD);
            socketFD = -1;
            if (acceptTimeout > 0) {
                long endTime = dbgsysCurrentTimeMillis();
                acceptTimeout -= (endTime - startTime);
                if (acceptTimeout <= 0) {
                    setLastError(JDWPTRANSPORT_ERROR_IO_ERROR,
                        "timeout waiting for debugger to connect");
                    return JDWPTRANSPORT_ERROR_IO_ERROR;
                }
            }
        }
    } while (socketFD < 0);

    return JDWPTRANSPORT_ERROR_NONE;
}