/* 
 * receive incoming packets from the specified socket, translate their 
 * addresses to network_address_t type, and call the user-supplied handler
 *
 * a network interrupt disables interrupts, so that we can cleanly return.
 * if interrupts were not disabled, and we were hit by a clock interrupt, it
 * would not be possible to return until we returned to the original stack.
 * this is inelegant, but we are constrained by ignorance of the minithread
 * struct format!
*/
int WINAPI network_poll(void* arg) {
  SOCKET* s;
  network_interrupt_arg_t* packet;
  struct sockaddr_in addr;
  int fromlen = sizeof(struct sockaddr_in);

  s = (SOCKET *) arg;

  for (;;) {

    /* we rely on run_user_handler to destroy this data structure */
    if (DEBUG)
      kprintf("NET:Allocating an incoming packet.\n");

    packet = 
      (network_interrupt_arg_t *) malloc(sizeof(network_interrupt_arg_t));
    assert(packet != NULL);
  
    packet->size = recvfrom(*s, packet->buffer, MAX_NETWORK_PKT_SIZE,
			    0, (struct sockaddr *) &addr, &fromlen);
    if (packet->size <= 0) {
      if(WSAGetLastError() == 10054){
        kprintf("NET: Broadcst attempt rejected (Are all my neighbors running?)\n");
        free(packet);
        continue;
      } else {
        kprintf("NET:Error, %d.\n", WSAGetLastError());
        AbortOnCondition(1,"Crashing.");
      }
    }
    else if (DEBUG)
      kprintf("NET:Received a packet, seqno %ld.\n", ntohl(*((int *) packet->buffer)));
   
    assert(fromlen == sizeof(struct sockaddr_in));
    sockaddr_to_network_address(&addr, packet->addr);

    /* 
     * now we have filled in the arg to the network interrupt service routine,
     * so we have to get the user's thread to run it.
     */
    if (DEBUG)
      kprintf("NET:packet arrived.\n");
    send_interrupt(NETWORK_INTERRUPT_TYPE, (void*)packet);
  }	
}
Esempio n. 2
0
int
network_poll(void* arg)
{
    int* s;
    network_interrupt_arg_t* packet;
    struct sockaddr_in addr;
    int fromlen = sizeof(struct sockaddr_in);

    s = (int *) arg;

    for (;;) {

        /* we rely on run_user_handler to destroy this data structure */
        if (DEBUG)
            kprintf("NET:Allocating an incoming packet.\n");

        packet =
            (network_interrupt_arg_t *) malloc(sizeof(network_interrupt_arg_t));
        assert(packet != NULL);

        packet->size = recvfrom(*s, packet->buffer, MAX_NETWORK_PKT_SIZE,
                                0, (struct sockaddr *) &addr, (socklen_t*) &fromlen);
        if (packet->size < 0) {
            kprintf("NET:Error, %d.\n", errno);
            AbortOnCondition(1,"Crashing.");
        } else if (DEBUG)
            kprintf("NET:Received a packet, seqno %ld.\n",
                    (long) ntohl(*((int *) packet->buffer)));

        assert(fromlen == sizeof(struct sockaddr_in));
        sockaddr_to_network_address(&addr, packet->addr);

        /*
         * now we have filled in the arg to the network interrupt service routine,
         * so we have to get the user's thread to run it.
         */
        if (DEBUG)
            kprintf("NET:packet arrived.\n");
        send_interrupt(NETWORK_INTERRUPT_TYPE, (void*)packet);
    }
}