Exemple #1
0
/* {{{ libssh2_packet_requirev
 * Loops libssh2_packet_read() until one of a list of packet types requested is available
 * SSH_DISCONNECT or a SOCKET_DISCONNECTED will cause a bailout
 * packet_types is a null terminated list of packet_type numbers
 */
int libssh2_packet_requirev_ex(LIBSSH2_SESSION *session, unsigned char *packet_types, unsigned char **data, unsigned long *data_len,
														 unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len)
{
	if (libssh2_packet_askv_ex(session, packet_types, data, data_len, match_ofs, match_buf, match_len, 0) == 0) {
		/* One of the packets listed was available in the packet brigade */
		return 0;
	}

	while (session->socket_state != LIBSSH2_SOCKET_DISCONNECTED) {
		int ret = libssh2_packet_read(session, 1);
		if (ret < 0) {
			return -1;
		}
		if (ret == 0) {
			continue;
		}

		if (strchr(packet_types, ret)) {
			/* Be lazy, let packet_ask pull it out of the brigade */
			return libssh2_packet_askv_ex(session, packet_types, data, data_len, match_ofs, match_buf, match_len, 0);
		}
	}

	/* Only reached if the socket died */
	return -1;
}
Exemple #2
0
int
libssh2_packet_requirev_ex(LIBSSH2_SESSION * session,
                           const unsigned char *packet_types,
                           unsigned char **data, unsigned long *data_len,
                           unsigned long match_ofs,
                           const unsigned char *match_buf,
                           unsigned long match_len,
                           packet_requirev_state_t * state)
{
    if (libssh2_packet_askv_ex
        (session, packet_types, data, data_len, match_ofs, match_buf,
         match_len, 0) == 0) {
        /* One of the packets listed was available in the packet
           brigade */
        state->start = 0;
        return 0;
    }

    if (state->start == 0) {
        state->start = time(NULL);
    }

    while (session->socket_state != LIBSSH2_SOCKET_DISCONNECTED) {
        int ret = libssh2_packet_read(session);
        if ((ret < 0) && (ret != PACKET_EAGAIN)) {
            state->start = 0;
            return ret;
        }
        if (ret <= 0) {
            long left = LIBSSH2_READ_TIMEOUT - (time(NULL) - state->start);

            if ((left <= 0) || (libssh2_waitsocket(session, left) <= 0)) {
                state->start = 0;
                return PACKET_TIMEOUT;
            } else if (ret == PACKET_EAGAIN) {
                return PACKET_EAGAIN;
            }
        }

        if (strchr((char *) packet_types, ret)) {
            /* Be lazy, let packet_ask pull it out of the brigade */
            return libssh2_packet_askv_ex(session, packet_types, data,
                                          data_len, match_ofs, match_buf,
                                          match_len, 0);
        }
    }

    /* Only reached if the socket died */
    state->start = 0;
    return -1;
}
Exemple #3
0
/* {{{ libssh2_packet_burn
 * Loops libssh2_packet_read() until any packet is available and promptly 
 * discards it
 * Used during KEX exchange to discard badly guessed KEX_INIT packets
 */
int
libssh2_packet_burn(LIBSSH2_SESSION * session,
                    libssh2_nonblocking_states * state)
{
    unsigned char *data;
    unsigned long data_len;
    unsigned char all_packets[255];
    int i;
    int ret;

    if (*state == libssh2_NB_state_idle) {
        for(i = 1; i < 256; i++) {
            all_packets[i - 1] = i;
        }

        if (libssh2_packet_askv_ex
            (session, all_packets, &data, &data_len, 0, NULL, 0, 0) == 0) {
            i = data[0];
            /* A packet was available in the packet brigade, burn it */
            LIBSSH2_FREE(session, data);
            return i;
        }

        _libssh2_debug(session, LIBSSH2_DBG_TRANS,
                       "Blocking until packet becomes available to burn");
        *state = libssh2_NB_state_created;
    }

    while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
        if ((ret = libssh2_packet_read(session)) == PACKET_EAGAIN) {
            return PACKET_EAGAIN;
        } else if (ret < 0) {
            *state = libssh2_NB_state_idle;
            return ret;
        } else if (ret == 0) {
            /* FIXME: this might busyloop */
            continue;
        }

        /* Be lazy, let packet_ask pull it out of the brigade */
        if (0 ==
            libssh2_packet_ask_ex(session, ret, &data, &data_len, 0, NULL, 0,
                                  0)) {
            /* Smoke 'em if you got 'em */
            LIBSSH2_FREE(session, data);
            *state = libssh2_NB_state_idle;
            return ret;
        }
    }

    /* Only reached if the socket died */
    return -1;
}
Exemple #4
0
/* {{{ libssh2_packet_burn
 * Loops libssh2_packet_read() until any packet is available and promptly discards it
 * Used during KEX exchange to discard badly guessed KEX_INIT packets
 */
int libssh2_packet_burn(LIBSSH2_SESSION *session)
{
	unsigned char *data;
	unsigned long data_len;
	char all_packets[255];
	int i;
	for(i = 1; i < 256; i++) all_packets[i - 1] = i;

	if (libssh2_packet_askv_ex(session, all_packets, &data, &data_len, 0, NULL, 0, 0) == 0) {
		i = data[0];
		/* A packet was available in the packet brigade, burn it */
		LIBSSH2_FREE(session, data);
		return i;
	}

#ifdef LIBSSH2_DEBUG_TRANSPORT
	_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Blocking until packet becomes available to burn");
#endif
	while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
		int ret = libssh2_packet_read(session, 1);
		if (ret < 0) {
			return -1;
		}
		if (ret == 0) continue;

		/* Be lazy, let packet_ask pull it out of the brigade */
		if (0 == libssh2_packet_ask_ex(session, ret, &data, &data_len, 0, NULL, 0, 0)) {
			/* Smoke 'em if you got 'em */
			LIBSSH2_FREE(session, data);
			return ret;
		}
	}

	/* Only reached if the socket died */
	return -1;
}