Esempio n. 1
0
static mol_dgram_t *
dgram_wait( int wait_what )
{
	mol_dgram_t *dg, **dgp;
	struct pollfd ufds;
	int timeout;
	
	ufds.fd = sv.fd;
	ufds.events = POLLIN;
	ufds.revents = 0;

	/* Search the queue... */
	for( dgp=&sv.queue; *dgp; dgp=&(**dgp).next ) {
		if( (**dgp).what == wait_what || !wait_what ) {
			dg = *dgp;
			*dgp = dg->next;

			recv_dgram( dg );
			return dg;
		}
	}

	for( ;; ) {
		int err;
		int n = poll( &ufds, 1, 10 /*ms*/ );
		if( !n && !wait_what )
			return NULL;
		if( !n ) {
			timeout++;
			continue;
		}
		
		if( n<0 ) {
			if( errno != EINTR )
				perrorm("poll");
			continue;
		}
		
		if( !(dg = receive_dgram( sv.dgram_receiver, &err )) )
			continue;
		if( wait_what == dg->what || !wait_what ) {
			recv_dgram( dg );
			break;
		}
		/* Enqueue */
		for( dgp=&sv.queue; *dgp; dgp=&(**dgp).next )
			;
		*dgp = dg;
	}
	return dg;
}
int send_probes (int ttl) 
{
  /* Removed to compile cleanly with -Wall */
  //int i;
  int probe, code, done;

  Setsockopt (sendfd, IPPROTO_IP, IP_TTL, &ttl, sizeof(int));
  bzero (salast, salen);

  printf ("%2d  ", ttl);
  fflush (stdout);

  done = 0; /* count the number of probes that generate an ICMP_DEST_UNREACH */

  for (probe = 0; probe < nprobes; probe++) {
    send_dgram (ttl);
    code = recv_dgram ();

    if (code == -3) {
      printf (" *");
    } else {
      print_report ();
    }

    if (code == -1) done++;
    fflush (stdout);
  }
  printf ("ms\n");
  return done;
}
Esempio n. 3
0
static void start() {
#ifdef TEST_IGMP
	send_igmp(selfaddr, allhostsgroup, IGMP_MEMBERSHIP_QUERY, 0, 0, NULL, 0);
#endif

	while (TRUE) {
		int recvLen;
		socklen_t fromLen;

#ifdef TEST_IGMP
		if (recv_igmp(NULL, NULL, NULL, NULL, 0) < 0) break;
#else
		if (recv_dgram(NULL, NULL, NULL, NULL, 0, TRUE) < 0) break;
#endif
	}
}
Esempio n. 4
0
void rcv_encoded(uint16_t *ids, uint16_t len, int sd, char *buf,
        struct sockaddr_in *client)
{
    int i;
    int dgram_num;
    uint16_t id;
    struct ip_header *iph = (struct ip_header*) buf;
    struct udp_header *udph = (struct udp_header *)
            (buf + sizeof(struct ip_header));
    uint16_t initid = ntohs(len);


    printf("Message length: %d\n", len);

    for (i = 0; i < len * 2; i++)
    {
        recv_dgram(sd, buf, client);

        id = ntohs(iph->id);

        if (ntohs(udph->srcport) != port_from_date()
                || IP_FLAGS(iph) == IP_DONTFRAG
                || !in_range(initid, id))
        {
            /* not one of our packets */
#ifdef DEBUG
            printf("A message we don't care about...\n");
            printf("  ntohs(udph->srcport):  %d\n", ntohs(udph->srcport));
            printf("  port_from_date():      %d\n", port_from_date());
            printf("  IP_FLAGS(iph):         %d\n", IP_FLAGS(iph));
            printf("  IP_DONTFRAG:           %d\n", IP_DONTFRAG);
            printf("  id:                    %d\n", id);
            printf("  in_range(initid, id):  %d\n", in_range(initid, id));
#endif
            i--;
            continue;
        }
        /* len is the initial ID */
        dgram_num = (id - initid) / 0x10;
        ids[dgram_num] = id;

        printf("#%d\tID: %d\n", dgram_num + 1, ntohs(iph->id));
    }
}
Esempio n. 5
0
JNIEXPORT void JNICALL Java_ow_ipmulticast_Native_receiveMulticast(JNIEnv *env, jclass clazz, jobject container) {
	struct ip *ip;
	struct udphdr *udp;
	char data[BUF_SIZE];
	int datalen = 0;
	jbyteArray jdata;

	if (recv_dgram(&ip, &udp, data, &datalen, BUF_SIZE, TRUE) < 0) {
		(*env)->ThrowNew(env, clazz_IOException, "recvfrom(2) returned -1.");
	}

	if (datalen >= BUF_SIZE) {
		log(LOG_WARNING, 0, "Buffer is possiblly too short.");

		datalen = BUF_SIZE;
	}

#ifdef RAW_OUTPUT_IS_RAW
	ip->ip_src.s_addr = ntohl(ip->ip_src.s_addr);
	ip->ip_dst.s_addr = ntohl(ip->ip_dst.s_addr);
	udp->source = ntohs(udp->source);
	udp->dest = ntohs(udp->dest);
#endif
	(*env)->SetIntField(env, container, field_MulticastMessage_srcaddr, (jint)(ip->ip_src.s_addr));
	(*env)->SetIntField(env, container, field_MulticastMessage_srcport, (jint)(udp->source));
	(*env)->SetIntField(env, container, field_MulticastMessage_destaddr, (jint)(ip->ip_dst.s_addr));
	(*env)->SetIntField(env, container, field_MulticastMessage_destport, (jint)(udp->dest));
	(*env)->SetIntField(env, container, field_MulticastMessage_id, (jint)(ip->ip_id));
	(*env)->SetIntField(env, container, field_MulticastMessage_ttl, (jint)(ip->ip_ttl));

	if (datalen > 0) {
		// jdata = new byte[datalen]; jdata[0..datale-1] = ...
		jdata = (*env)->NewByteArray(env, (jsize)datalen);
		(*env)->SetByteArrayRegion(env, jdata, (jsize)0, (jsize)datalen, (jbyte *)data);

		// container.data = jdata
		(*env)->SetObjectField(env, container, field_MulticastMessage_data, (jobject)jdata);
	}
}
Esempio n. 6
0
void server()
{
    struct sockaddr_in server;
    struct sockaddr_in client;
    int sd;
    char buf[RECV_BUFLEN];
    uint16_t len;
    uint16_t *ids;
    char *decoded;

    struct ip_header *iph = (struct ip_header*) buf;
    struct udp_header *udph = (struct udp_header *)
            (buf + sizeof(struct ip_header));


    if ((sd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)) == -1)
    {
        exit(sock_error("socket()", 0));
    }

    memset((char *) &server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(DST_PORT);
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    
    if (bind(sd, (struct sockaddr *) &server, sizeof(server)) == -1)
    {
        exit(sock_error("bind()", 0));
    }

    while (1)
    {
        recv_dgram(sd, buf, &client);

        if (ntohs(udph->srcport) == port_from_date()
                && IP_FLAGS(iph) == IP_DONTFRAG)
        {
            printf("Covert message arriving...\n");
            len = iph->id;
            ids = malloc(sizeof(uint16_t) * len * 2);
            decoded = malloc(sizeof(char) * len + 1);

            rcv_encoded(ids, len, sd, buf, &client);
            printf("Message received. Decoding...\n\n");

            decode(decoded, ids, len);
            printf("%s\n", decoded);

            free(ids);
            free(decoded);
        }
#ifdef DEBUG
        else
        {
            printf("A message we don't care about...\n");
            printf("  ntohs(udph->srcport):  %d\n", ntohs(udph->srcport));
            printf("  port_from_date():      %d\n", port_from_date());
            printf("  IP_FLAGS(iph):         %d\n", IP_FLAGS(iph));
            printf("  IP_DONTFRAG:           %d\n", IP_DONTFRAG);
        }
#endif
    }
}
Esempio n. 7
0
void net::Socket::wait(size_t &recv, size_t &sent, statistics * stats) {
    dgram *sent_pkt, recv_pkt;
    bool *sndr_acked, *recv_acked;
    int *timeouts;

    sent_pkt = (dgram*)calloc(sizeof(dgram), params.window_size);
    sndr_acked = (bool*)calloc(sizeof(bool), params.window_size);
    recv_acked = (bool*)calloc(sizeof(bool), params.window_size);
    timeouts = (int*)calloc(sizeof(int), params.window_size);

    // Initialize to 0
    recv = 0;
    sent = 0;

    // Initialize
    for (int i = 0; i < params.window_size; i++) {
        data(sent_pkt[i], -1, 0, NULL);
        recv_acked[i] = false;
        sndr_acked[i] = false;
        timeouts[i] = 0;
    }

    if (stats != NULL) {
        stats->packets_required = (sndr_len / params.payload_size);
        if ((sndr_len % params.payload_size) > 0) stats->packets_required++;
        stats->transfer_time = clock();
        stats->packets_sent = 0;
    }

    //std::cout << "INIT JOBS: Sender(" << sndr_len << ", #" << sndr_seqno << "), Receiver(" << recv_len << ", #" << recv_seqno << ")\n";

    // Loop until there is no job left.
    while (sndr_len > 0 || recv_len > 0) {

        if (sndr_len > 0) {
            // We have some outstanding bytes to send.
            for (int i = 0; i < params.window_size; i++) {
                if (timeouts[i] > 0) continue; // Already sent, waiting for ACK
                if (sndr_acked[i]) continue; // Already ACKed
                if (sndr_len > i * params.payload_size) {
                    sent_pkt[i].size = min(params.payload_size, sndr_len - (i * params.payload_size));
                }
                else {
                    sent_pkt[i].size = 0;
                }
                if (sent_pkt[i].size == 0) continue; // Not a real packet (beyond our send buffer)
                data(sent_pkt[i], (sndr_seqno + i) % SEQNO_MAX, sent_pkt[i].size, sndr_buf + (i*params.payload_size));
                if (trace) tracefile << "SENDER: Sending packet #" << sent_pkt[i].seqno << " of size " << sent_pkt[i].size << "\n";
                send_dgram(sent_pkt[i]);
                timeouts[i] = params.timeout;
                if (stats != NULL) stats->packets_sent++;
            }
        }

        // Wait for a packet.
        clock_t begin_time = clock();
        int status = recv_dgram(recv_pkt);
        int recv_elapsed = (clock() - begin_time) / (CLOCKS_PER_SEC / 1000);

        if (status == SOCKET_ERROR) {
            if (WSAGetLastError() == WSAETIMEDOUT) {
                // Complete silence on the wire, try sending ALL packets again
                for (int i = 0; i < params.window_size; i++) {
                    timeouts[i] = 0;
                }
                continue;
            }
            // This is another type of error.
            traceError(WSAGetLastError(), "SOCKET_ERROR while waiting for packet.");
            throw new SocketException("Could not receive packet!");
        }

        // Update timeouts according to time elapsed during recv
        for (int i = 0; i < params.window_size; i++) {
            timeouts[i] -= recv_elapsed;
        }

        // We have something; how we react depends on the type of packet received.
        switch (recv_pkt.type) {
        case SYNACK:
            // Last ACK of connection handshake was lost. Re-ACK it.
            send_ack(recv_pkt);
            break; // Go back to waiting.
        case ACK:
            // Were we waiting for one of these?
            if (sndr_len > 0) {
                // Yes. Is this one of the ones we were waiting for?
                for (int i = 0; i < params.window_size; i++) {
                    if (sent_pkt[i].size < 0) continue; // Not a real packet.
                    if (sndr_acked[i]) continue; // Already ACKed, so whatever
                    if (recv_pkt.seqno == sent_pkt[i].seqno) {
                        if (trace) tracefile << "SENDER: Received ACK for packet #" << recv_pkt.seqno << "\n";
                        // Yes. Packet was acknowledged.
                        sndr_acked[i] = true;
                    }
                }
                // Slide the sender window until we have a non-acked packet heading it
                while (sndr_acked[0]) {
                    // Update sender state
                    sndr_seqno = nextSeqNo(sndr_seqno);
                    sndr_buf += sent_pkt[0].size;
                    sndr_len -= sent_pkt[0].size;
                    sent += sent_pkt[0].size;

                    // Slide window
                    for (int j = 0; j < params.window_size - 1; j++) {
                        sent_pkt[j] = sent_pkt[j + 1];
                        timeouts[j] = timeouts[j + 1];
                        sndr_acked[j] = sndr_acked[j + 1];
                    }
                    // The new "last packet" is automatically timed out because it has never been sent yet
                    data(sent_pkt[params.window_size - 1], -1, 0, NULL);
                    timeouts[params.window_size - 1] = 0;
                    sndr_acked[params.window_size - 1] = false;
                }
            }
            // In all other cases, simply discard.
            break;
        case DATA:
            // Were we waiting for one of these?
            if (recv_len > 0) {
                for (int i = 0; i < params.window_size; i++) {
                    size_t buf_offset = (i * params.payload_size);
                    if (buf_offset >= recv_len) continue; // Ignore window entries beyond buffer size
                    int seqno = (recv_seqno + i) % SEQNO_MAX;
                    if (recv_pkt.seqno == seqno) {
                        // Packet falls within window.
                        if (!recv_acked[i]) {
                            // Check that packet size matches expected size
                            size_t expected_size = min(params.payload_size, recv_len - (i * params.payload_size));
                            if (expected_size != recv_pkt.size) {
                                // Problematic case: we received a DATA packet with the correct SeqNo but wrong number of bytes
                                if (trace) tracefile << "RECEIVER: Packet #" << recv_pkt.seqno << " has unexpected size " << recv_pkt.size << " (expected " << expected_size << ").\n";
                                // This is DEFINITELY an un-recoverable error.
                                throw new SocketException("RECEIVER: DATA packet has correct sequence number but wrong size!");
                            }
                            // This is the first time we receive this packet.
                            if (trace) tracefile << "RECEIVER: Received expected DATA packet #" << recv_pkt.seqno << " of size " << recv_pkt.size << "\n";
                            memcpy(recv_buf + buf_offset, recv_pkt.payload, recv_pkt.size); // Copy payload bytes into buffer
                            recv_acked[i] = true;
                        }
                    }
                }
                // ACK the packet we have received
                if (trace) tracefile << "RECEIVER: Acknowledged packet #" << recv_pkt.seqno << "\n";
                send_ack(recv_pkt);
                // Slide the receiver window, if necessary.
                while (recv_acked[0]) {
                    // Update receiver state
                    size_t pktsize = min(params.payload_size, recv_len);

                    recv_seqno = nextSeqNo(recv_seqno);
                    recv_len -= pktsize;
                    recv_buf += pktsize;
                    recv += pktsize;

                    // Slide window
                    for (int j = 0; j < params.window_size - 1; j++) {
                        recv_acked[j] = recv_acked[j + 1];
                    }
                    recv_acked[params.window_size - 1] = false;
                }
            }
            else {
                // Problematic case: we received a DATA packet while we were not expecting any
                if (recv_seqno == recv_pkt.seqno) {
                    // This is the 1000$ bug that's not covered in the textbook
                    // Other side has switched mode and is sending early.
                    // Do NOT acknowledge this packet.
                    if (trace) tracefile << "RECEIVER: Unexpected packet #" << recv_pkt.seqno << " with size " << recv_pkt.size << " will NOT be acknowledged.\n";
                }
                else {
                    // This is probably an old DATA packet, acknowledge it
                    if (trace) tracefile << "RECEIVER: Acknowledging unexpected packet #" << recv_pkt.seqno << " with " << recv_pkt.size << " bytes.\n";
                    send_ack(recv_pkt);
                }
            }
            break;

        default:
            break; // Default is to discard packet.
        }
    }
    if (stats != NULL) {
        stats->transfer_time = (clock() - stats->transfer_time) / (CLOCKS_PER_SEC / 1000);
    }
    //std::cout << "FINISH JOBS: Sender(" << sndr_len << ", #" << sndr_seqno << "), Receiver(" << recv_len << ", #" << recv_seqno << ")\n";
    free(sent_pkt);
    free(recv_acked);
    free(sndr_acked);
    free(timeouts);
}
Esempio n. 8
0
void net::ServerSocket::listen(int backlog) {
    // Wait for a SYN
    dgram _syn, _synack, _ack;
    if (trace) tracefile << "SERVER: Waiting for SYN message\n";
    while (true) {
        int recvbytes = recv_dgram(_syn, true);
        if (recvbytes == SOCKET_ERROR) {
            if (WSAGetLastError() == WSAETIMEDOUT) continue; // Timed out, try again
            // Some other error occured
            traceError(WSAGetLastError(), "SOCKET_ERROR while recv");
            throw new SocketException("Could not receive SYN from a client!");
        }
        if (recvbytes < sizeof(dgram)) continue; // Throw away unexpected packet
        if (_syn.type != SYN) {
            if (_syn.type == DATA) {
                // Last packet of previous connection was dropped or delayed
                send_ack(_syn);
            }
            continue; //Throw away unexpected packet
        }

        break;
    }
    recv_seqno = nextSeqNo(_syn.seqno);

    if (trace) tracefile << "SERVER: Received SYN with Seq No " << _syn.seqno << "\n";

    // Complete the connection handshake.
    // Send a SYNACK
    synack(_synack, _syn);
    if (trace) tracefile << "SERVER: Sending SYNACK with Seq No " << _synack.seqno << "\n";
    send_dgram(_synack);

    if (trace) tracefile << "SERVER: Waiting for acknowledgement of SYNACK\n";
    while (true) {

        // Wait for ACK
        int recvbytes = recv_dgram(_ack);
        if (recvbytes == SOCKET_ERROR) {
            if (WSAGetLastError() == WSAETIMEDOUT) {
                // Timed out, re-send packet
                if (trace) tracefile << "SERVER: Timed-out, re-sending SYNACK\n";
                send_dgram(_synack);
                continue;
            }
            // Some other error occured
            traceError(WSAGetLastError(), "SOCKET_ERROR while recv");
            throw new SocketException("Could not receive SYNACK from client!");
        }
        if (recvbytes < sizeof(dgram)) continue; // Throw away unexpected packet
        if (_ack.type != ACK) continue; //Throw away unexpected packet
        if (_ack.seqno != _synack.seqno) {
            continue; // This ACK is not for our SYNACK!
        }

        if (trace) tracefile << "SERVER: Received ACK with Seq No " << _ack.seqno << "\n";
        break;
    }

    std::cout << "Accepted connection from " << inet_ntoa(dest.sin_addr) << ":"
              << std::hex << htons(dest.sin_port) << std::dec << std::endl;

    sndr_seqno = nextSeqNo(_synack.seqno);

    if (trace) {
        tracefile << "SERVER: Received SYNACK acknowledgement, connection established!\n";
        tracefile << "Next sequence numbers will be:\n";
        tracefile << "  Client: " << recv_seqno << "\n";
        tracefile << "  Server: " << sndr_seqno << "\n";
    }
}
Esempio n. 9
0
net::ClientSocket::ClientSocket(int af, int protocol, bool trace, int local_port, const struct sockaddr_in * name, int namelen) :
    Socket(af, protocol, trace) {

    local_addr.sin_family = AF_INET;
    local_addr.sin_port = htons(local_port);
    local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    // This is dumb, but the router requires that the client socket binds to a static port.
    if (SOCKET_ERROR == ::bind(winsocket, (const sockaddr*)&local_addr, sizeof(local_addr))) {
        traceError(WSAGetLastError(), "SOCKET_ERROR while binding");
        throw new SocketException("Could not bind client socket!");
    }

    dest = *name;
    dest_len = namelen;

    // Three-way handshake.
    // Step 1: Send the sequence number to the server
    dgram _syn;
    syn(_syn);
    if (trace) tracefile << "CLIENT: Sending SYN message with Seq No " << _syn.seqno << "\n";
    int sentbytes = send_dgram(_syn);
    if (sentbytes == SOCKET_ERROR) {
        traceError(WSAGetLastError(), "SOCKET_ERROR while sendto");
        throw new SocketException("Could not send SYN");
    }

    sndr_seqno = nextSeqNo(_syn.seqno);

    // Step 2: Wait for SYNACK
    if (trace) tracefile << "CLIENT: Waiting for SYNACK message\n";
    while (true) {

        dgram _synack;
        int recvbytes = recv_dgram(_synack);
        if (recvbytes == SOCKET_ERROR) {
            if (WSAGetLastError() == WSAETIMEDOUT) {
                // Timed out, re-send syn
                send_dgram(_syn);
                continue; // Timed out, try again
            }
            // Some other error occured
            traceError(WSAGetLastError(), "SOCKET_ERROR while recv");
            throw new SocketException("Could not receive SYNACK message from server!");
        }
        if (recvbytes < sizeof(dgram)) continue; // Throw away unexpected packet
        if (_synack.type != SYNACK) continue; //Throw away unexpected packet

        if (trace) tracefile << "CLIENT: Received SYNACK with Seq No " << _synack.seqno << "\n";

        recv_seqno = nextSeqNo(_synack.seqno);

        // Step 3: Send ACK
        if (trace) tracefile << "CLIENT: Sending ACK in response to SYNACK\n";
        // Simulate loss of packet!
        send_ack(_synack);

        break;
    }
    if (trace) {
        tracefile << "CLIENT: Connection established!\n";
        tracefile << "Next sequence numbers will be:\n";
        tracefile << "  Client: " << sndr_seqno << "\n";
        tracefile << "  Server: " << recv_seqno << "\n";
    }
}