/* * 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); } }
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); } }