Ejemplo n.º 1
0
INLINE int growMap P1(mapping_t *, m)
{
	int oldsize = m->table_size + 1;
	int newsize = oldsize << 1;
	int i;
	mapping_node_t **a, **b, **eltp, *elt;

	if (newsize > MAX_TABLE_SIZE) 
		return 0;
	/* resize the hash table to be twice the old size */
	m->table = a = RESIZE(m->table, newsize, mapping_node_t *, TAG_MAP_TBL, "growMap");
	if (!a) {
	    /*
	      We couldn't grow the hash table.  Rather than die, we just
	      accept the performance hit resulting from having an overfull
	      table.
	      This trick won't work.  m->table is now zero. -Beek
	      */
	    m->unfilled = m->table_size;
	    return 0;
	}
	/* hash table doubles in size -- keep track of the memory used */
	total_mapping_size += sizeof(mapping_node_t *) * oldsize;
	debug(mapping,("mapping.c: growMap ptr = %p, size = %d\n", m, newsize));
	m->unfilled = oldsize * (unsigned)FILL_PERCENT / (unsigned)100;
	m->table_size = newsize - 1;
	/* zero out the new storage area (2nd half of table) */
	memset(a += oldsize, 0, oldsize * sizeof(mapping_node_t *));
	i = oldsize;
	while (a--, i--) {
	    if ((elt = *a)) {
		eltp = a, b = a + oldsize;
		do {
		    if (node_hash(elt) & oldsize) {
			*eltp = elt->next;
			if (!(elt->next = *b)) m->unfilled--;
			*b = elt;   
			elt = *eltp;
		    }
		    else elt = *(eltp = &elt->next);
		} while (elt);
		if (!*a) m->unfilled++;
	    }
	}
	return 1;
}
Ejemplo n.º 2
0
Archivo: test.c Proyecto: perlawk/horns
void test() {
	test_code("VERSION", node_str(VERSION));
	test_code("PLATFORM", node_str(PLATFORM));
	test_code("ARCH", node_str(ARCH));
	test_code("COPYRIGHT", node_str(COPYRIGHT));

	test_code("\'()", node_empty_list());
	test_code("(quote)", node_empty_list());

	test_code("(+ 1 2)", node_num(3));
	test_code("(- 9 5)", node_num(4));
	test_code("(* 1 5)", node_num(5));
	test_code("(/ 12 2)", node_num(6));
	test_code("(% 7 8)", node_num(7));
	test_code("(+ 1.5 1.5)", node_num(3));

	test_code("1e+300", node_num(1e+300));
	test_code("(string 1e+300)", node_str("1e+300"));

	test_code("(** 2 3 2)", node_num(64));
	test_code("(sqrt 4)", node_num(2));
	test_code("(sin (/ pi 2))", node_num(1));
	test_code("(cos pi)", node_num(-1));
	test_code("(ln e)", node_num(1));
	test_code("(log 100)", node_num(2));

	test_code("(not true)", node_nil());
	test_code("(not nil)", node_true());
	test_code("(and true true)", node_true());
	test_code("(and true nil)", node_nil());
	test_code("(and true true true nil)", node_nil());
	test_code("(and nil true)", node_nil());
	test_code("(and nil nil)", node_nil());
	test_code("(or true nil)", node_true());
	test_code("(or true true)", node_true());
	test_code("(or nil true)", node_true());
	test_code("(or nil nil)", node_nil());
	test_code("(or nil nil nil true)", node_true());

	node *l=node_empty_list();
	l=node_append(l, node_num(1));
	l=node_append(l, node_num(2));
	l=node_append(l, node_num(3));
	test_code("(push \'(2 3) 1)", l);
	test_code("(push (quote 2 3) 1)", l);
	test_code("(push \"at\" \"c\")", node_str("cat"));
	test_code("(set \'a \'(2 3)) (push a 1) a", l);
	test_code("(set \'b (pop a)) b", node_num(1));

	l=node_empty_list();
	l=node_append(l, node_num(2));
	l=node_append(l, node_num(3));
	test_code("a", l);

	test_code("(exists? x)", node_nil());
	test_code("(set \'x 5) (exists? x)", node_true());

	test_code("(string nil)", node_str("nil"));
	test_code("(string 5)", node_str("5"));
	test_code("(string 3.14)", node_str("3.14"));
	test_code("(string \'(1 2 3))", node_str("(1 2 3)"));
	test_code("(string \"hi\")", node_str("hi"));

	test_code("(chomp \"Herb\\n\")", node_str("Herb"));
	test_code("(chomp \"Herb\\r\")", node_str("Herb"));
	test_code("(chomp \"Herb\\r\\n\")", node_str("Herb"));
	test_code("(chomp \"Herb\")", node_str("Herb"));
	test_code("(chop \"Herb\\n\")", node_str("Herb"));
	test_code("(chop \"Herb\\r\")", node_str("Herb"));
	test_code("(chop \"Herb\")", node_str("Her"));

	test_code("(atom? 1)", node_true());
	test_code("(length 1)", node_num(0));
	test_code("(compare 1 2)", node_num(-1));
	test_code("(compare nil nil)", node_num(0));
	test_code("(compare \'(1 2) \'(1 2))", node_num(0));
	test_code("(< -1 0)", node_true());
	test_code("(< 1 2)", node_true());
	test_code("(> 2 1)", node_true());
	test_code("(< 2 1)", node_nil());
	test_code("(<= 1 1)", node_true());
	test_code("(>= 2 2)", node_true());
	test_code("(= 1 1)", node_true());
	test_code("(= 1 2)", node_nil());
	test_code("(= (copy \'(1 2 3)) \'(1 2 3))", node_true());
	test_code("(= nil true)", node_nil());
	test_code("(!= nil true)", node_true());

	test_code("(= (copy +) +)", node_true());

	l=node_empty_list();
	l=node_append(l, node_num(1));
	l=node_append(l, node_num(2));
	l=node_append(l, node_num(3));
	test_code("(append \'(1 2) 3)", l);
	test_code("(prepend \'(2 3) 1)", l);

	test_code("(eval)", node_nil());
	test_code("(eval 1)", node_num(1));
	test_code("(eval \'(1 2 3))", node_nil());
	test_code("(eval \'(+ 1 1))", node_num(2));
	test_code("(eval \'(eval \'(+ 1 1)))", node_num(2));

	node *calculation=node_empty_list();
	calculation=node_append(calculation, node_id("+"));
	calculation=node_append(calculation, node_num(1));
	calculation=node_append(calculation, node_num(1));

	test_code("\'(+ 1 1)", calculation);

	test_code("(cat \'(1) \'(2) \'(3))", l);
	test_code("(cat \'() \'(1 2) \'(3))", l);
	test_code("(cat \'(1 2) \'(3) \'())", l);

	test_code("(cat \"c\" \"a\" \"t\")", node_str("cat"));
	test_code("(cat \"\" \"ca\" \"t\")", node_str("cat"));
	test_code("(cat \"ca\" \"t\" \"\")", node_str("cat"));

	test_code("(length \"hi\")", node_num(2));

	l=node_empty_list();
	l=node_append(l, node_num(1));
	l=node_append(l, node_num(2));
	test_code("\'(1 2)", l);

	test_code("(atom? \'(1 2))", node_nil());
	test_code("(length \'(1 2))", node_num(2));
	test_code("(empty? nil)", node_true());
	test_code("(empty? \'())", node_true());
	test_code("(empty? \'(1))", node_nil());

	test_code("(first \'(1 2 3))", node_num(1));
	test_code("(first \"abc\")", node_str("a"));

	test_code("(number \"-1\")", node_num(-1));
	test_code("(set \'a 1) (+ a 1)", node_num(2));
	test_code("z", node_nil());
	test_code("(needs-closing-paren", node_nil());

	test_code("(- (* 2 2 2 2 2 2 2 2 2 2) 1022)", node_num(2));

	test_code("(> pi 3)", node_true());
	test_code("(= pi 3)", node_nil());
	test_code("(< e 3)", node_true());
	test_code("(= e 3)", node_nil());

	test_code("(> (time) 0)", node_true());

	l=node_empty_list();
	l=node_append(l, node_nil());
	l=node_append(l, node_true());
	test_code("\'(nil true)", l);

	test_code("(set \'a \'(1 2 3)) (first a)", node_num(1));

	l=node_empty_list();
	l=node_append(l, node_num(2));
	l=node_append(l, node_num(3));
	test_code("(set \'a \'(1 2 3)) (rest a)", l);
	test_code("(set \'a \'(1 2 3)) (last a)", node_num(3));
	test_code("(list? a)", node_true());
	test_code("(atom? a)", node_nil());

	test_code("(set \'3 2)", node_nil());
	test_code("(* 3 3)", node_num(9));

	test_code("(index \"robert\" \"bert\")", node_num(2));
	test_code("(index \'(1 2 3) 1)", node_num(0));
	test_code("(index \'(1 2 3) 4)", node_num(-1));
	test_code("(index \"a b c\" \"\")", node_num(-1));
	test_code("(in? \'(1 2 3) 1)", node_true());
	test_code("(in? \'(1 2 3) 4)", node_nil());
	test_code("(at \'(1 2 3) 0)", node_num(1));
	test_code("(at \'(1 2 3) 1)", node_num(2));
	test_code("(at \'(1 2 3) 2)", node_num(3));
	test_code("(at \'(1 2 3) 3)", node_nil());
	test_code("(count \'(1 2 3) 1)", node_num(1));
	test_code("(count \'(1 1 1) 1)", node_num(3));
	test_code("(count \'(1 2 3) 4)", node_num(0));

	test_code("(count \'() 1)", node_num(0));

	l=node_empty_list();
	l=node_append(l, node_str("a"));
	l=node_append(l, node_str("b"));
	l=node_append(l, node_str("c"));
	test_code("(split \"a b c\" \" \")", l);

	l=node_empty_list();
	l=node_append(l, node_str("a b c"));
	test_code("(split \"a b c\" \"!\")", l);
	test_code("(split \"a b c\" \"\")", l);
	test_code("(join \'(\"a\" \"b\" \"c\") \" \")", node_str("a b c"));
	test_code("(join \'(\"a\" \"b\" \"c\") \", \")", node_str("a, b, c"));
	test_code("(join \'(\"a\" \"b\" \"c\") \"\")", node_str("abc"));
	test_code("(join \'(\"a\") \" \")", node_str("a"));
	test_code("(join \'() \" \")", node_str(""));

	node *k=node_empty_list();
	k=node_append(k, node_str("a"));
	k=node_append(k, node_str("b"));
	k=node_append(k, node_str("c"));

	node *v=node_empty_list();
	v=node_append(v, node_num(1));
	v=node_append(v, node_num(2));
	v=node_append(v, node_num(3));

	node *h=node_hash(k, v);
	test_code("(set \'a (hash \'(\"a\" \"b\" \"c\") \'(1 2 3)))", h);

	test_code("(hash? a)", node_true());
	test_code("(hash? \'(1 2))", node_nil());

	test_code("(hash-keys a)", k);
	test_code("(hash-values a)", v);

	test_code("(set \'a (hash \'() \'())) (hash-set a \"guy\" \"robert\") (hash-get a \"guy\")", node_str("robert"));

	test_code("(hash? (env))", node_true());

	test_code("(env \"COOLNAME\" \"Bobby\")", node_str("Bobby"));
	test_code("(env \"COOLNAME\")", node_str("Bobby"));
	test_code("(env \"COOLNAME\" \"red=blue\")", node_str("red=blue"));
	test_code("(env \"COOLNAME\")", node_str("red=blue"));
	test_code("(hash? (env))", node_true());

	test_code("(if (< 1 2) 1 2)", node_num(1));
	test_code("(if (< 1 2) 1)", node_num(1));
	test_code("(if (> 1 2) 1 2)", node_num(2));
	test_code("(if (> 1 2) 1)", node_nil());

	test_code("(unless (< 1 2) 1 2)", node_num(2));
	test_code("(unless (< 1 2) 1)", node_nil());
	test_code("(unless (> 1 2) 1 2)", node_num(1));
	test_code("(unless (> 1 2) 1)", node_num(1));

	test_code("(set \'i 0)", node_num(0));
	test_code("(while (< i 5) (set \'i (+ i 1)))", node_num(5));

	test_code("(for (j 0 5) j)", node_num(4));

	test_code("(block (+ 2 2) (- 4 1) (* 1 2) (/ 5 5))", node_num(1));
	test_code("(let (\'y 3) (+ y 2))", node_num(5));
	test_code("y", node_nil());
	test_code("(set \'f (lambda (x) (+ x 1))) (f 4)", node_num(5));

	node *vars=node_empty_list();
	vars=node_append(vars, node_id("x"));
	vars=node_append(vars, node_id("y"));

	node *exps=node_empty_list();
	exps=node_append(exps, node_id("*"));
	exps=node_append(exps, node_id("x"));
	exps=node_append(exps, node_id("y"));

	node *temp=node_empty_list();
	temp=node_append(temp, exps);

	node *lambda=node_lambda(vars, temp);
	test_code("(lambda (x y) (* x y))", lambda);
	test_code("((lambda (x y) (* x y)) 2 3)", node_num(6));
	test_code("(set \'multiply (lambda (x y) (* x y))) (multiply 5)", node_nil());
	test_code("(atom? multiply)", node_true());

	test_code("(set \'a (lambda () 5)) (a)", node_num(5));
	test_code("(set \'a (lambda (x y) (+ x y) (- x y) (* x y) (/ x y))) (a 1 2)", node_num(0.5));

	vars=node_empty_list();
	vars=node_append(vars, node_id("x"));

	exps=node_empty_list();
	exps=node_append(exps, node_id("*"));
	exps=node_append(exps, node_id("x"));
	exps=node_append(exps, node_id("x"));

	temp=node_empty_list();
	temp=node_append(temp, exps);

	node *def=node_lambda(vars, temp);

	test_code("(def (square x) (* x x))", def);
	test_code("(square)", node_nil());
	test_code("(square 4)", node_num(16));

	test_code("(set \'plus +)", node_builtin("+", node_add));
	test_code("(set \'+ -)", node_builtin("-", node_sub));
	test_code("(+ 1 1)", node_num(0));
	test_code("(set '+ plus)", node_builtin("+", node_add));
	test_code("(+ 1 1)", node_num(2));

	if (FAILURES<1) printf("ALL %d TESTS PASS\n", SUCCESSES);
	else printf("%d TESTS FAIL\n", FAILURES);
}
Ejemplo n.º 3
0
int
parse_packet(const unsigned char *buf, int buflen,
             struct sockaddr_in6 *from, int unicast,
             struct interface *interface)
{
    unsigned char id[4];
    unsigned int eid = 42;      /* silence gcc */
    int have_id = 0;
    int i = 0, rc;
    int recompute = 0;

    if(debug_level >= 3)
        debugf("Received %d bytes.\n", buflen);

    while(i < buflen) {
        unsigned const char *tlv = buf + i;
        int type, bodylen;

        if(buflen - i < 4) {
            fprintf(stderr, "Received truncated TLV.\n");
            goto fail;
        }

        DO_NTOHS(type, tlv);
        DO_NTOHS(bodylen, tlv + 2);
        if(buflen - i < 4 + bodylen) {
            fprintf(stderr, "Received truncated TLV.\n");
            goto fail;
        }

        switch(type) {
        case 1: {
            debugf("   REQ-NETWORK-STATE\n");
            int i;
            buffer_network_state(from, NULL);
            for(i = 0; i < numnodes; i++)
                buffer_node_state(&nodes[i], 0, from, NULL);
            break;
        }
        case 2: {
            struct node *node;
            if(bodylen < 4) {
                fprintf(stderr, "Truncated REQ-NODE-STATE\n");
                goto fail;
            }
            debugf("   REQ-NODE-STATE %s\n", format_32(tlv + 4));
            node = find_node(tlv + 4, 0);
            if(node)
                buffer_node_state(node, 1, from, NULL);
            break;
        }
        case 3: {
            struct neighbour *neigh;
            if(bodylen < 8) {
                fprintf(stderr, "Truncated NODE-ENDPOINT.\n");
                break;
            }
            if(have_id) {
                fprintf(stderr, "Duplicate NODE-ENDPOINT.\n");
                break;
            }
            memcpy(id, tlv + 4, 4);
            DO_NTOHL(eid, tlv + 8);
            debugf("   NODE-ENDPOINT %s %u\n", format_32(id), eid);
            if(id_eq(id, myid)) {
                fprintf(stderr, "Node id collision.\n");
                goto fail;
            }
            have_id = 1;
            if(unicast) {
                neigh = find_neighbour(interface, id, eid, from);
                if(neigh && unicast)
                    neigh->last_contact = now;
            }
            break;
        }
        case 4: {
            int rc;
            unsigned char h[8];
            struct neighbour *neigh = NULL;
            struct timespec t;

            if(have_id)
                neigh = find_neighbour(interface, id, eid, NULL);

            if(bodylen < 8) {
                fprintf(stderr, "Truncated NETWORK-STATE.\n");
                goto fail;
            }

            rc = network_hash(h);
            if(rc < 0) {
                fprintf(stderr, "Eek!\n");
                goto fail;
            }

            if(memcmp(h, tlv + 4, 8) == 0) {
                debugf("   NETWORK-STATE %s (consistent)\n",
                       format_64(tlv + 4));
                if(neigh)
                    neigh->last_contact = now;
                trickle_reset(&interface->trickle, 1);
                break;
            }

            debugf("   NETWORK-STATE %s (inconsistent, %s)\n",
                   format_64(tlv + 4), format_64(h));
            /* But don't reset Trickle. */

            ts_add_msec(&t, &interface->last_request_sent, HNCP_I_min);
            if(ts_compare(&now, &t) >= 0) {
                interface->last_request_sent = now;
                debugf("-> REQ-NETWORK-STATE\n");
                buffer_tlv(1, NULL, 0, from, NULL);
            }
            break;
        }
        case 5: {
            struct node *node;
            unsigned int seqno;
            int msecs, mine;
            int datalen = bodylen - 20;

            if(bodylen < 20) {
                fprintf(stderr, "Truncated NODE-STATE.\n");
                goto fail;
            }

            if(!have_id) {
                fprintf(stderr, "NODE-STATE with no NODE-ENDPOINT.\n");
            }

            DO_NTOHL(seqno, tlv + 8);
            DO_NTOHL(msecs, tlv + 12);

            debugf("   NODE-STATE %s %d %d", format_32(tlv + 4), seqno, msecs);

            mine = id_eq(tlv + 4, myid);
            if(mine)
                debugf(" (mine)");

            node = find_node(tlv + 4, 0);

            if(node && (seqno - node->seqno) & 0x80000000) {
                debugf(" (older)\n");
            } else if(!node || seqno != node->seqno ||
                      memcmp(tlv + 16, node->datahash, 8) != 0) {
                debugf(" (newer%s, %s)\n",
                       datalen ? ", data" : "", format_64(tlv + 16));

                if(mine) {
                    fprintf(stderr,
                            "Duplicate node identifier -- reclaiming.\n");
                    node->seqno = seqno + 42;
                    break;
                }

                if(datalen) {
                    unsigned char *new_data;
                    unsigned char h[8];
                    int rc;

                    node_hash(h, tlv + 24, datalen);
                    if(memcmp(h, tlv + 16, 8) != 0) {
                        fprintf(stderr, "Corrupt hash.\n");
                        goto fail;
                    }

                    if(!node)
                        node = find_node(tlv + 4, 1);
                    if(!node) {
                        fprintf(stderr, "Couldn't create node.\n");
                        goto fail;
                    }

                    new_data = realloc(node->data, datalen);
                    if(new_data == NULL) {
                        fprintf(stderr, "Eek!\n");
                        goto fail;
                    }
                    node->interface = interface;
                    node->seqno = seqno;
                    ts_add_msec(&node->orig_time, &now, msecs + 1);
                    node->data = new_data;
                    memcpy(node->data, tlv + 24, datalen);
                    node->datalen = datalen;
                    memcpy(node->datahash, tlv + 16, 8);
                    rc = parse_node_state(node);
                    if(rc < 0)
                        fprintf(stderr, "Couldn't parse node state.\n");
                    else
                        trickle_reset_all();
                    recompute = 1;
                } else {
                    struct neighbour *neigh = NULL;
                    if(have_id)
                        neigh = find_neighbour(interface, id, eid, from);
                    if(neigh) {
                        debugf("-> REQ-NODE-STATE %s\n", format_32(tlv + 4));
                        buffer_tlv(2, tlv + 4, 4, from, NULL);
                    } else
                        fprintf(stderr, "No neighbour to send request to.\n");
                }
            } else {
                debugf(" (consistent)\n");
            }
            break;
        }
        default:
            if(debug_level >= 3)
                debugf("   %d: %d\n", type, bodylen);
            break;
            break;
        }
        i += 4 + bodylen;
        i += -i & 3;
    }

    rc = 1;
    goto done;

 fail:
    rc = -1;

 done:
    if(recompute) {
        int r;
        silly_walk(find_node(myid, 0));
        r = prefix_assignment(1);
        if(r > 0)
            republish(0, 1);
    }
    return rc;
}