Esempio n. 1
0
/*
 * Limit the flow to only receiving from one remote end point.
 */
static int udp_connect(struct socket *sock, const struct sockaddr *address,
		       int address_len)
{
    struct sockaddr_in *inaddr= (struct sockaddr_in *)address;
    struct udp_data    *ud= (struct udp_data *)sock->data;    

    if(address->sa_family != AF_INET)
    {
	printf("udp_connect: non INET family %d\n", address->sa_family);
	return -1;
    }

    if (sock->state != SS_BOUND)
    {
	printf("udp_connect: socket is not in bound state (%d != %d)\n",
		sock->state, SS_BOUND);
	return -1;
    }

    memcpy(&(sock->raddr), inaddr, sizeof(struct sockaddr_in));

    /* build the stack if needed */
    if (sock->state != SS_CONNECTED)
    {
	if (!build_stack((struct udp_data *)sock->data,
			 (struct sockaddr_in *)&(sock->laddr),
			 (struct sockaddr_in *)&(sock->raddr)))
	{
	    printf("udp_connect: problem with building stack\n");
	    return -1;
	}
	sock->state = SS_CONNECTED;
    }
    else
    {
	FlowMan_SAP	lsap, rsap;
	struct sockaddr_in *laddr;
	struct sockaddr_in *raddr;
	FlowMan_ConnID	cid;
	
	/* the stack's already been built, so we just need to swizzle the
	 * packet filters (send() will retarget the stack as needed) */
	laddr = (struct sockaddr_in *)&sock->laddr;
	raddr = (struct sockaddr_in *)&sock->raddr;
	lsap.tag = FlowMan_PT_UDP;
	lsap.u.UDP.addr.a = laddr->sin_addr.s_addr;
	lsap.u.UDP.port = laddr->sin_port;
	rsap.tag = FlowMan_PT_UDP;
	rsap.u.UDP.addr.a = raddr->sin_addr.s_addr;
	rsap.u.UDP.port = raddr->sin_port;
	cid = UDP$GetConnID(ud->udp);
	if (!FlowMan$ReAttach(ud->fman, ud->flow, cid, &lsap, &rsap))
	{
	    printf("ReAttach failed!\n");
	    return False;
	}
    }

    return 0;
}
// @breadth_order : The other of breadth first visit is the order of node allocation
GraphHandle build_graph_with_cycles(uint32_t size) {
  GraphHandle graph = build_graph_dag(size);
  Stack stack = build_stack(graph.vertex_count);
  VisitorState visit_state = { .user_state = &stack };

  // we are going to mutate the graph while we traverse it
  // to avoid messing with the traversal, we mutate the nodes on our way out
  two_way_depth_first_traversal((Node*)graph.root, &visit_state, 
      build_graph_with_cycles_in_helper, build_graph_with_cycles_out_helper);

  free_stack(&stack);
  return graph;
}
Esempio n. 3
0
int main(int argc, char* argv[])
{
	int i;
	node * m;

	/* obligatory */
	printf("Hello, World\r\n");
	printf("\r\n---\r\n");

	/* Node stuff */

	printf("Creating and destroying 10000 nodes\r\n");
	for (i = 0; i < 10000 ; i++)
	{
		int data = i;
		node * n = build_node(&data);
		destroy_node(n);
	}
	printf("Done\r\n");

	printf("\r\n---\r\n");

	printf("Building a queue, adding 10000 nodes. Printing out every 1000\r\n");
	queue * q = build_queue();

	for (i = 0; i < 10000 ; i++)
	{
		int data = i;
		node * n = build_node(&data);
		queue_push(q, n);
	}
	printf("Queue has the size %d\r\n", q->size);

	for (i = 0; i < 10000 ; i++)
	{
		node * n = queue_pop(q);
		if((i%1000)==0)
		{
			printf("Node has the data %d\r\n", *(int*)n->data);
		}
		destroy_node(n);
	}
	printf("Queue has the size %d\r\n", q->size);

	destroy_queue(q);
	printf("\r\n---\r\n");

	printf("Building a stack, adding 10000 nodes. Printing out every 1000\r\n");
	stack * s = build_stack();

	for (i = 0; i < 10000 ; i++)
	{
		int data = i;
		node * n = build_node(&data);
		stack_push(s, n);
	}
	printf("Stack has the size %d\r\n", s->size);

	for (i = 0; i < 10000 ; i++)
	{
		node * n = stack_pop(s);
		if((i%1000)==0)
		{
			printf("Node has the data %d\r\n", *(int*)n->data);
		}
		destroy_node(n);
	}
	printf("Stack has the size %d\r\n", s->size);

	destroy_stack(s);
	printf("\r\n---\r\n");
	
	printf("Building a linked list, adding 10000 nodes. Printing out every 1000\r\n");
	llist * l = build_llist();

	for (i = 0; i < 10000 ; i++)
	{
		int data = i;
		node * n = build_node(&data);
		llist_add(l, n);
	}
	printf("llist has the size %d\r\n", l->size);
	
	printf("Testing arbitrary access...\r\n");
	m = llist_get(l, 87);
  printf("Node has the data %d\r\n", *(int*)m->data);
  m = llist_get(l, 3487);
  printf("Node has the data %d\r\n", *(int*)m->data);
  m = llist_get(l, 287);
  printf("Node has the data %d\r\n", *(int*)m->data);
  
  printf("Testing arbitrary delete...\r\n");
  
  m = llist_get(l, 299);
  printf("Node has the data %d\r\n", *(int*)m->data);
  llist_delete(l, 299);
  m = llist_get(l, 299);
  printf("Node has the data %d\r\n", *(int*)m->data);

	printf("Testing mass delete...\r\n");
	destroy_llist(l);
	
	printf("\r\n---\r\n");
	
	printf("Creating and destroying 10000 single trees\r\n");
	for (i = 0; i < 10000 ; i++)
	{
		int data = i;
		tree * n = build_tree(&data);
		destroy_tree(n);
	}
	printf("Done\r\n");

	printf("\r\n---\r\n");
	
	printf("Testing add/delete for trees\r\n");
	int data = 2;
	tree * root = build_tree(&data);
	
	//for (i = 0; i < 3 ; i++)
//	{
//		int data = i;
//		tree * n = build_tree(&data);
//		destroy_tree(n);
//		add_leaf(&root, n, &tree_int_comp);
//	}
	
	data = 1;
	tree * leaf1 = build_tree(&data);
	add_leaf(&root, leaf1, &tree_int_comp);
	
	data = 0;
	tree * leaf2 = build_tree(&data);
	add_leaf(&root, leaf2, &tree_int_comp);
	
	printf("Root node has value %d before deletion\r\n", *(int*)root->data);
	delete_node(&(root));
	printf("Root node has value %d after deletion\r\n", *(int*)root->data);
	
	destroy_tree(leaf1);
	destroy_tree(leaf2);
	
	printf("Done\r\n");

	return 0;
}
Esempio n. 4
0
static int udp_select(struct socket *sock, int nfds,
		      fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
		      struct timeval *timeout)
{
    IO_Rec rec;
    uint32_t nrecs;
    word_t value;
    Time_ns t;
    struct udp_data *udp_data= (struct udp_data *)sock->data;

    MU_LOCK(&sock->lock);

    /* XXX really want to keep a domain-wide cache of connections */
    if(sock->state != SS_CONNECTED) /* stack needs building */
    {
	struct sockaddr_in *laddr = (struct sockaddr_in *)&(sock->laddr);

	/* remote address isn't used for anything in recv */
	build_stack(udp_data, laddr, NULL);
	sock->state = SS_CONNECTED;
    }
    MU_RELEASE(&sock->lock);
    MU_LOCK(&sock->rxlock);

    if (timeout)
    {
	t = NOW() + 
	    timeout->tv_sec * SECONDS(1) + 
	    timeout->tv_usec * MICROSECS(1);
    }
    else
    {
	t = FOREVER;
    }

    value = 0;
    IO$GetPkt(udp_data->rxio, 0, &rec, t, &nrecs, &value);
    if (value)
    {
	eprintf("udp_select: got a packet cx?!?\n");
	ntsc_dbgstop();
    }

#ifdef PARANOID
    if (NOW() > t + SECONDS(2))
	printf("udp_select: warning: took >2 secs to return from select?\n");
#endif

    MU_RELEASE(&sock->rxlock);

    if (nrecs)
    {
//	eprintf("sel ok\n");
	return 1;  /* there's data available */
    }
    else
    {
//	eprintf("sel t/o\n");
	return 0;  /* no data, but not an error - we timed out */
    }
}
Esempio n. 5
0
static int udp_send(struct socket *sock, const char *message, int len,
		    int flags, const struct sockaddr *dest_addr, int dest_len)
{
    struct udp_data *udp_data= (struct udp_data *)sock->data;
    IO_Rec txrecs[3];
    struct sockaddr_in *laddr= (struct sockaddr_in *)&(sock->laddr);
    struct sockaddr_in *raddr= (struct sockaddr_in *)&(sock->raddr);
    int i;
    uint32_t nrecs;
    pktcx_t *pktcx;

    TRC(eprintf("udp_send: entered\n"));

    MU_LOCK(&sock->lock);

    if(sock->state != SS_CONNECTED) /* stack needs building */
    {
	if (dest_addr)
	{
	    *raddr = *(struct sockaddr_in *)dest_addr;
	}
	else
	{
	    MU_RELEASE(&sock->lock);
	    return -1; /* ENOTCONN or summit */
	}

	TRC(eprintf("udp_send: building stack\n"));
	build_stack(udp_data, laddr, NULL);
	sock->state = SS_CONNECTED;

	/* now target it */
	TRC(eprintf("udp_send: retargeting to %I:%d\n",
		    raddr->sin_addr, raddr->sin_port));
	if(!retarget(udp_data, laddr, raddr)) {
	    TRC(eprintf("...retarget failed\n"));
	    /* ARP failed */
	    MU_RELEASE(&sock->lock);
	    return -1; /* EHOSTDOWN or sim */
	}
    }
    else
    {
	struct sockaddr_in *daddr = (struct sockaddr_in *)dest_addr;

	TRC(eprintf("udp_send: stack already built\n"));
	if (daddr->sin_addr.s_addr == raddr->sin_addr.s_addr
	    && daddr->sin_port == raddr->sin_port)
	{
	    TRC(eprintf("... and targeted correctly\n"));
	}
	else
	{
	    TRC(eprintf("... but incorrectly targeted; retargeting\n"));
	    /* retarget stack for this destination */
	    if(!retarget(udp_data, laddr, daddr)) {
		/* ARP failed */
		MU_RELEASE(&sock->lock);
		return -1; /* EHOSTDOWN or sim */
	    }
	    *raddr = *daddr;
	    TRC(eprintf("udp_send: retargeted stack\n"));
	}
    }

    /* done with global state, now need the acquire the receive resource
     * lock */
    MU_RELEASE(&sock->lock);
    MU_LOCK(&sock->txlock);

    /* organise mem for headers */
    txrecs[0].len  = udp_data->head;
    txrecs[0].base = udp_data->txbuf;

    /* 
    ** XXX SMH: for the moment, we must copy the data to be transmitted
    ** onto a heap which is readable by the driver domain. This is not, 
    ** however, the most efficient way one can imagine doing transmit.
    ** Some alternatives that should be investigated are:
       a) make the driver enter kernel mode s.t. it can read the data.
          This is essentially what used to happen before coz drivers
	  ran in kernel mode the entire time. 
       b) map the clients data readable to the driver domain on the fly.
          This would require some way of getting hold of the stretch
	  containing the message buffer, and might be a very bad idea
	  indeed coz lots of other stuff would be mapped too.
       c) force clients to give us data which is readable by the driver
          pdom. This is trickier than it sounds since in general clients
	  won't know the pdom of the driver for the interface upon which
	  their message will eventually be transmitted. Though we could
	  arrange for all network drivers to be in the same pdom (!?!).
    ** Even apart from those considerations, this temporary solution should
    ** be modified s.t. the mallocing is done out of band, or not at all
    ** [i.e. perhaps have a stretch, not a heap, and then can just memcpy
    **  to the start of this. requires some locking though ;-]
    */
    txrecs[1].len  = len;
    if(!(txrecs[1].base = Heap$Malloc(udp_data->txheap, len))) {
	eprintf("udp_send: failed to malloc txrec buf!\n"); 
	MU_RELEASE(&sock->txlock); 
	return -1;   /* error */
    }
    memcpy((char *)txrecs[1].base, message, len);

    if(!(pktcx = Heap$Calloc(udp_data->txheap, sizeof(pktcx_t), 1))) {
	eprintf("udp_send: failed to malloc packet context!\n"); 
	Heap$Free(udp_data->txheap, txrecs[1].base);
	MU_RELEASE(&sock->txlock); 
	return -1;   /* error */
    }

    pktcx->ri_nrecs = 2;
    for(i=0; i<2; i++)
	pktcx->ri_recs[i] = txrecs[i];

    TRC(eprintf("udp_send: About to IO$PutPkt...\n"));


    if (!IO$PutPkt(udp_data->txio, 2, txrecs, (word_t)pktcx, FOREVER))
    {
	txrecs[1].len = -1;  /* error */
	goto out;
    }

    /* pick up the tx buffer from the driver */
    do {
	IO$GetPkt(udp_data->txio, 2, txrecs, NOW() + SECONDS(10),
		  &nrecs, (word_t*)&pktcx);
	if (nrecs == 0) {
	    printf("udp_send: timeout recovering tx buffers\n");
	} else {
	    if (nrecs != 2)
	    {
		printf("udp_send: didn't recover enough tx buffers (%d!=3)\n",
		       nrecs);
	    }
	}
    } while(nrecs != 2);
    if (!pktcx)
	printf("udp_send: didn't get packet context back?\n");
    if (pktcx && pktcx->error)
	printf("udp_send: error %d sending\n", pktcx->error);

out:
    Heap$Free(udp_data->txheap, txrecs[1].base);
    Heap$Free(udp_data->txheap, pktcx);

    MU_RELEASE(&sock->txlock);

    return txrecs[1].len;
}
Esempio n. 6
0
/* 
** listen doesn't make much sense on UDP
*/
static int udp_listen(struct socket *sock)
{
    printf("XXX bad call listen on udp/dgram/inet socket.\n");
    return -1;
}


#define MAXRECS 18	/* which is enough for 6 fragments */
static int udp_recv(struct socket *sock, char *buffer, int length, int flags, 
		    struct sockaddr *address, int *address_len)
{
    struct sockaddr_in *inaddr  = (struct sockaddr_in *)address;
    struct udp_data    *udp_data= (struct udp_data *)sock->data;
    IO_Rec rxrecs[MAXRECS];
    word_t value;
    uint32_t nrecs;
    uint32_t cnt=0;
    int rxlen=0;
    int i;
    pktcx_t *pktcx, *np;

    MU_LOCK(&sock->lock);

    /* XXX really want to keep a domain-wide cache of connections */
    if(sock->state != SS_CONNECTED) /* stack needs building */
    {
	struct sockaddr_in *laddr = (struct sockaddr_in *)&(sock->laddr);

	/* remote address isn't used for anything in recv */
	build_stack(udp_data, laddr, NULL);
	sock->state = SS_CONNECTED;
    }

    /* done with global state, now need the acquire the receive resource
     * lock */
    MU_RELEASE(&sock->lock);
    MU_LOCK(&sock->rxlock);

    do {
	/* organise mem for header */
	IO$GetPkt(udp_data->rxio, MAXRECS, rxrecs, FOREVER, &nrecs, &value);
	pktcx = (void*)value;
	if (nrecs > MAXRECS)
	{
	    printf("udp_recv: %d recs needed, only %d supplied\n",
		   nrecs, MAXRECS);
	    goto fail;
	}
	if (!pktcx)
	{
	    printf("udp_recv: didn't get back a pktcx?\n");
	    goto fail;
	}
	if (nrecs > 0)
	{
	    for(i=1; i<nrecs; i++)
	    {
		if (rxrecs[i].len == 0)
		    continue;  /* skip empty recs */
		cnt = MIN(rxrecs[i].len, length);
		if (cnt == 0)
		    break;	/* out of client buffer */
		memcpy(buffer, rxrecs[i].base, cnt);
		buffer += cnt;
		length -= cnt;
		rxlen += cnt;
	    }
	}
	else /* nrecs == 0 */
	{
	    /* no valid data, but the packet context probably contains
	     * some recs for us, so recyle the buffers and try
	     * receiving again */
	    eprintf("udp: recycle (shouldn't happen)\n");
	    while(pktcx)
	    {
		np = pktcx->next;
		pktcx->next = NULL;	/* break any chain */
		pktcx->error = 0;
		pktcx->cid = 0;
		IO$PutPkt(udp_data->rxio, pktcx->ri_nrecs, pktcx->ri_recs,
			  (word_t)pktcx, FOREVER);
		pktcx = np;
	    }
	    /* back to the top... */
	}
    } while(nrecs == 0);

    if (cnt == 0)
    {
	printf("udp_recv: warning: truncated the received packet "
		"to fit buffer\n");
    }
    
    TRC(eprintf("udp_recv: got back %d recs.\n", nrecs));

    if (inaddr)
    {
	FlowMan_SAP sap;

	inaddr->sin_family = AF_INET;
	if (UDP$GetLastPeer(udp_data->udp, &sap))
	    inaddr->sin_addr.s_addr = sap.u.UDP.addr.a;
	else
	    inaddr->sin_addr.s_addr = 0;  /* IP layer not present */
	inaddr->sin_port = sap.u.UDP.port;
	*address_len = sizeof(*inaddr);
    }

    /* send empty buffer(s) back down */
    TRC(eprintf("udp_recv: sending buffers back down\n"));
    while(pktcx)
    {
	np = pktcx->next;
	pktcx->next = NULL;	/* break any chain */
	pktcx->error = 0;
	pktcx->cid = 0;
	nrecs = pktcx->ri_nrecs;
	for(i=0; i<nrecs; i++)
	    rxrecs[i] = pktcx->ri_recs[i];
	IO$PutPkt(udp_data->rxio, nrecs, rxrecs, (word_t)pktcx, FOREVER);
	pktcx = np;
    }

    MU_RELEASE(&sock->rxlock);
    return rxlen;

fail:
    MU_RELEASE(&sock->rxlock);
    return -1;
}