示例#1
0
static void
test_pqueue_add_fail_val_oor(void)
{
    struct pqueue q;
    struct pqueue_node nodes[1];
    int rc;
    bwputstr(COM2, "test_pqueue_add_fail_val_oor...");
    pqueue_init(&q, ARRAY_SIZE(nodes), nodes);
    rc = pqueue_add(&q, 1, 42);
    assert(rc == -1);
    rc = pqueue_add(&q, 2, 42);
    assert(rc == -1);
    bwputstr(COM2, "ok\n");
}
示例#2
0
static void
test_pqueue_add_fail_duplicate1(void)
{
    struct pqueue q;
    struct pqueue_node nodes[2];
    int rc;
    bwputstr(COM2, "test_pqueue_add_fail_duplicate1...");
    pqueue_init(&q, ARRAY_SIZE(nodes), nodes);
    rc = pqueue_add(&q, 0, 42);
    assert(rc == 0);
    rc = pqueue_add(&q, 1, 3);
    assert(rc == 0);
    rc = pqueue_add(&q, 1, 55);
    assert(rc == -2);
    bwputstr(COM2, "ok\n");
}
示例#3
0
static void
test_pqueue_add2_popmin2_peekmin(void)
{
    struct pqueue q;
    struct pqueue_node nodes[2];
    struct pqueue_entry *min;
    int rc;
    bwputstr(COM2, "test_pqueue_add2_popmin2_peekmin...");
    pqueue_init(&q, ARRAY_SIZE(nodes), nodes);
    rc = pqueue_add(&q, 0, 1);
    assert(rc == 0);
    rc = pqueue_add(&q, 1, 0);
    assert(rc == 0);
    pqueue_popmin(&q);
    pqueue_popmin(&q);
    min = pqueue_peekmin(&q);
    assert(min == NULL);
    bwputstr(COM2, "ok\n");
}
示例#4
0
static void
test_pqueue_add2_peekmin_fst(void)
{
    struct pqueue q;
    struct pqueue_node nodes[2];
    struct pqueue_entry *min;
    int rc;
    bwputstr(COM2, "test_pqueue_add2_peekmin_fst...");
    pqueue_init(&q, ARRAY_SIZE(nodes), nodes);
    rc = pqueue_add(&q, 1, -1);
    assert(rc == 0);
    rc = pqueue_add(&q, 0, 0);
    assert(rc == 0);
    min = pqueue_peekmin(&q);
    assert(min != NULL);
    assert(min->key == -1);
    assert(min->val == 1);
    bwputstr(COM2, "ok\n");
}
示例#5
0
static void test_pqueue_many(void)
{
    struct pqueue q;
    struct pqueue_node nodes[32];
    struct pqueue_entry *min;
    int keys[32] = {
        1, 20, 28, 0, 12, 12, 21, 29, 25, 22, 13, 18, 2, 31, 21, 8,
        13, 10, 9, 2, 21, 20, 14, 14, 14, 21, 20, 31, 18, 13, 3, 24
    };
    bool incl[32];
    int i, j, count, rc;

    for (i = 0; i < 32; i++)
        incl[i] = false;

    bwputstr(COM2, "test_pqueue_many...");
    pqueue_init(&q, 32, nodes);

    count = 0;
    i = 0;
    while (count <= 16 - 2) {
        rc = pqueue_add(&q, i, keys[i]);
        assert(rc == 0);
        incl[i++] = true;
        rc = pqueue_add(&q, i, keys[i]);
        assert(rc == 0);
        incl[i++] = true;
        min = pqueue_peekmin(&q);
        assert(min != NULL);
        assert(incl[min->val]);
        assert(keys[min->val] == min->key);
        for (j = 0; j < 32; j++)
            assert(!incl[j] || keys[j] >= min->key);
        incl[min->val] = false;
        pqueue_popmin(&q);
        count++;
    }

    while (count > 0) {
        min = pqueue_peekmin(&q);
        assert(min != NULL);
        assert(incl[min->val]);
        assert(keys[min->val] == min->key);
        for (j = 0; j < 32; j++)
            assert(!incl[j] || keys[j] >= min->key);
        incl[min->val] = false;
        pqueue_popmin(&q);
        count--;
        if (count > 0 && count % 2 == 0) {
            for (i = 0; i < 32; i++) {
                if (incl[i])
                    break;
            }
            keys[i] = -i;
            rc = pqueue_decreasekey(&q, i, -i);
            assert(rc == 0);
        }
    }

    min = pqueue_peekmin(&q);
    assert(min == NULL);
    bwputstr(COM2, "ok\n");
}
示例#6
0
/*** decaps_gre ***************************************************************/
int decaps_gre (int fd, callback_t callback, int cl)
{
    unsigned char buffer[PACKET_MAX + 64 /*ip header*/];
    struct pptp_gre_header *header;
    int status, ip_len = 0;
    static int first = 1;
    unsigned int headersize;
    unsigned int payload_len;
    u_int32_t seq;

    if ((status = read (fd, buffer, sizeof(buffer))) <= 0) {
        warn("short read (%d): %s", status, strerror(errno));
        stats.rx_errors++;
        return -1;
    }
    /* strip off IP header, if present */
    if ((buffer[0] & 0xF0) == 0x40) 
        ip_len = (buffer[0] & 0xF) * 4;
    header = (struct pptp_gre_header *)(buffer + ip_len);
    /* verify packet (else discard) */
    if (    /* version should be 1 */
            ((ntoh8(header->ver) & 0x7F) != PPTP_GRE_VER) ||
            /* PPTP-GRE protocol for PPTP */
            (ntoh16(header->protocol) != PPTP_GRE_PROTO)||
            /* flag C should be clear   */
            PPTP_GRE_IS_C(ntoh8(header->flags)) ||
            /* flag R should be clear   */
            PPTP_GRE_IS_R(ntoh8(header->flags)) ||
            /* flag K should be set     */
            (!PPTP_GRE_IS_K(ntoh8(header->flags))) ||
            /* routing and recursion ctrl = 0  */
            ((ntoh8(header->flags)&0xF) != 0)) {
        /* if invalid, discard this packet */
        warn("Discarding GRE: %X %X %X %X %X %X", 
                ntoh8(header->ver)&0x7F, ntoh16(header->protocol), 
                PPTP_GRE_IS_C(ntoh8(header->flags)),
                PPTP_GRE_IS_R(ntoh8(header->flags)), 
                PPTP_GRE_IS_K(ntoh8(header->flags)),
                ntoh8(header->flags) & 0xF);
        stats.rx_invalid++;
        return 0;
    }
    /* silently discard packets not for this call */
    if (ntoh16(header->call_id) != pptp_gre_call_id) return 0;
    /* test if acknowledgement present */
    if (PPTP_GRE_IS_A(ntoh8(header->ver))) { 
        u_int32_t ack = (PPTP_GRE_IS_S(ntoh8(header->flags)))?
            header->ack:header->seq; /* ack in different place if S = 0 */
        ack = ntoh32( ack);
        if (ack > ack_recv) ack_recv = ack;
        /* also handle sequence number wrap-around  */
        if (WRAPPED(ack,ack_recv)) ack_recv = ack;
        if (ack_recv == stats.pt.seq) {
            int rtt = time_now_usecs() - stats.pt.time;
            stats.rtt = (stats.rtt + rtt) / 2;
        }
    }
    /* test if payload present */
    if (!PPTP_GRE_IS_S(ntoh8(header->flags)))
        return 0; /* ack, but no payload */
    headersize  = sizeof(*header);
    payload_len = ntoh16(header->payload_len);
    seq         = ntoh32(header->seq);
    /* no ack present? */
    if (!PPTP_GRE_IS_A(ntoh8(header->ver))) headersize -= sizeof(header->ack);
    /* check for incomplete packet (length smaller than expected) */
    if (status - headersize < payload_len) {
        warn("discarding truncated packet (expected %d, got %d bytes)",
                payload_len, status - headersize);
        stats.rx_truncated++;
        return 0; 
    }
    /* check for expected sequence number */
    if ( first || (seq == seq_recv + 1)) { /* wrap-around safe */
	if ( log_level >= 2 )
            log("accepting packet %d", seq);
        stats.rx_accepted++;
        first = 0;
        seq_recv = seq;
        return callback(cl, buffer + ip_len + headersize, payload_len);
    /* out of order, check if the number is too low and discard the packet. 
     * (handle sequence number wrap-around, and try to do it right) */
    } else if ( seq < seq_recv + 1 || WRAPPED(seq_recv, seq) ) {
	if ( log_level >= 1 )
            log("discarding duplicate or old packet %d (expecting %d)",
                seq, seq_recv + 1);
        stats.rx_underwin++;
    /* sequence number too high, is it reasonably close? */
    } else if ( seq < seq_recv + MISSING_WINDOW ||
                WRAPPED(seq, seq_recv + MISSING_WINDOW) ) {
	stats.rx_buffered++;
        if ( log_level >= 1 )
            log("%s packet %d (expecting %d, lost or reordered)",
                disable_buffer ? "accepting" : "buffering",
                seq, seq_recv+1);
        if ( disable_buffer ) {
            seq_recv = seq;
            stats.rx_lost += seq - seq_recv - 1;
            return callback(cl, buffer + ip_len + headersize, payload_len);
        } else {
            pqueue_add(seq, buffer + ip_len + headersize, payload_len);
	}
    /* no, packet must be discarded */
    } else {
	if ( log_level >= 1 )
            warn("discarding bogus packet %d (expecting %d)", 
		 seq, seq_recv + 1);
        stats.rx_overwin++;
    }
    return 0;
}