Пример #1
0
int32_t send_buf(uint8_t *buf, uint32_t len, Connection *conn, uint8_t flag, uint32_t seq_num)
{
  uint8_t packet[MAX_PACKET_LEN];
  int32_t send_len = 0;
  uint16_t checksum = 0;

  if (len > 0) {
    memcpy(&packet[7], buf, len);
  }

  seq_num = htonl(seq_num);
  memcpy(packet, &seq_num, 4);
  packet[6] = flag;

  memset(&packet[4], 0, 2);
  checksum = in_cksum((unsigned short *)packet, len+8);
  memcpy(&packet[4], &checksum, 2);

  if ((send_len = sendtoErr(conn->socket_num, packet, len+8, 0, (struct sockaddr *)&conn->remote, conn->len)) < 0) {
    perror("send_buf:sendto");
    exit(1);
  }

  // printf("send_buf: len: %u seq: %u flag: %u sum:%u\n", send_len, ntohl(seq_num), flag, checksum);

  return send_len;
}
Пример #2
0
void srj_connect(srjconn_t *conn)
{
    uint8_t *payload = conn->buffer + sizeof(srjhdr_t);
    srjhdr_t *hdr = (srjhdr_t *)conn->buffer;
    size_t packet_len = sizeof(srjconn_t) + 2 * sizeof(uint32_t) + 
                        sizeof(uint16_t);

    hdr->flag  = SRJ_FLAG_FNAME;
    hdr->seq   = 0;
    hdr->cksum = 0;

    memcpy(payload, &conn->window_size, sizeof(uint32_t));
    memcpy(payload + sizeof(uint32_t), &conn->buffer_size, sizeof(uint32_t));

    hdr->cksum = in_cksum((unsigned short *)conn->buffer, packet_len);

    sendtoErr(
            conn->sk, 
            conn->buffer, 
            packet_len, 
            0, 
            (struct sockaddr *)&conn->remote, 
            sizeof(struct sockaddr_in)
    );
}
Пример #3
0
int32_t send_buf(uint8_t *buf, uint32_t len, Connection *connection, uint8_t flag, uint32_t seq_num, uint8_t *packet)
{
    int32_t send_len = 0;
    uint16_t checksum = 0;
    
    /* set up the packet(seq#, crc, flag, data) */
    if (len > 0)
        memcpy(&packet[7] , buf, len);
            
    seq_num = htonl(seq_num);
    memcpy(&packet[0], &seq_num, 4);
    packet[6] = flag;
    
    memset(&packet[4], 0, 2);
    
    checksum = in_cksum((unsigned short *)packet, len + 8);
    
    memcpy(&packet[4], &checksum, 2);
    
    if ((send_len = sendtoErr(connection->sk_num, packet, len + 8, 0, (struct sockaddr *) &(connection->remote), connection->len)) < 0)
    {
        perror("in udp send_buf, sendtoErr");
        exit(-1);
    }
    
    return send_len; 
}
Пример #4
0
STATE timeout_on_ack(uint8_t * packet, int32_t packet_len)
{
    if(sendtoErr(server.sk_num, packet, packet_len, 0, (struct sockaddr *) &(server.remote), server.len) < 0)
    {
        perror("timeout_on_ack sendto");
        exit(-1);
    }
    return WAIT_ON_ACK;
}
Пример #5
0
Client::State Client::recvPackets() {
    packet inpkt;
    packet outpkt;

    // Check for timeout
    switch (recvPacket(inpkt)) {
    case 1:
        // Receive error.
        return ERROR;
    case 2:
        // Bad checksum or timeout.
        outpkt = rejpkt(mvSequence);
        break;
    default:
        // if sequence is less than or equal to our own, send RR.  Even if it's
        // lower than it's supposed to be, we'll just send the RR to make the
        // server feel better about itself.
        if (inpkt.sequence <= mvSequence) {
            mvRetries = PKT_TRNSMAX;
            outpkt = rrpkt(inpkt.sequence);
            
            if (inpkt.sequence == mvSequence) {
                mvSequence++;
                
                if (writeTo(inpkt) == 1) {
                    return ERROR;
                }
                
                if (inpkt.type == PKT_TYPE_DAT && inpkt.size < mvBufferSize) {
                    // A valid, less-than-maximum sized packet indicates
                    // end-of-file
                    return DONE;
                }
            }
        } else {
            // if the sequence is outright wrong, however...
            std::cout << "Received packet with incorrect sequence.  Expected "
                      << mvSequence << " or lower.  Received " << inpkt.sequence
                      << std::endl;
            outpkt = rejpkt(mvSequence);
        }
    }
    
    // Send response packet
    if (sendtoErr(mvSocket, &outpkt, sizeof(packet), 0, (sockaddr *)&mvAddr,
                  mvAddrLen) == -1)
    {
        std::cerr << "sendto (" << __LINE__ << "): " << strerror(errno)
                  << std::endl;
        return ERROR;
    }
    
    return RECV_PACKETS;
}
Пример #6
0
void send_pkt(pkt *Pkt, int socket, struct sockaddr_in dst_addr)
{
    int flags = 0;
    int dst_addr_len = (int)sizeof(dst_addr);
    if (Pkt != NULL && Pkt->datagram != NULL)
    {
        //      printf("--Send--\n");
        //      print_hdr(Pkt);
        //      printf("--------\n");
        sendtoErr(socket, Pkt->datagram, Pkt->datagram_len, flags,
                  (struct sockaddr *)&dst_addr, dst_addr_len);

    }

    else
        fprintf(stderr, "send_pkt argument error\n");
}
Пример #7
0
Client::State Client::init() {
    // Build packets
    packet pkt[5];
    
    // connection packet
    memset(&pkt[0], PKT_TYPE_CXN, sizeof(packet));
    pkt[0].checksum = 0;
    pkt[0].sequence = 0;
    pkt[0].checksum = in_cksum((unsigned short *)&pkt[0], sizeof(packet));
    
    // 2nd stage connection response
    memset(&pkt[1], PKT_TYPE_CXN2, sizeof(packet));
    pkt[1].sequence = 1;
    pkt[1].checksum = 0;
    pkt[1].checksum = in_cksum((unsigned short *)&pkt[1], sizeof(packet));
    
    // buffer size packet
    memset(&pkt[2], PKT_TYPE_BUF, sizeof(packet));
    pkt[2].size = mvBufferSize;
    pkt[2].sequence = 2;
    pkt[2].checksum = 0;
    pkt[2].checksum = in_cksum((unsigned short *)&pkt[2], sizeof(packet));

    // window size packet
    memset(&pkt[3], PKT_TYPE_WIN, sizeof(packet));
    pkt[3].size = mvWindowSize;
    pkt[3].sequence = 3;
    pkt[3].checksum = 0;
    pkt[3].checksum = in_cksum((unsigned short *)&pkt[3], sizeof(packet));

    // file name packet
    memset(&pkt[4], PKT_TYPE_FLN, sizeof(packet));
    memcpy(pkt[4].data, mvFromName.c_str(), mvFromName.length()+1);
    pkt[4].data[mvFromName.length()] = '\0';
    pkt[4].sequence = 4;
    pkt[4].checksum = 0;
    pkt[4].checksum = in_cksum((unsigned short *)&pkt[4], sizeof(packet));
    
    // Send packets
    int sk; // new socket
    mvOldSocket = mvSocket;
    sockaddr_storage addr;
    for (int i = 0; i < 5 && mvRetries > 0; i++) {
        packet inpkt;
        int r;
        
        // Send packet
        if (sendtoErr(mvSocket, &pkt[i], sizeof(packet), 0, (sockaddr *)&mvAddr,
                      mvAddrLen) == -1) {
            std::cerr << "sendto (" << __LINE__ << "): " << strerror(errno)
                      << std::endl;
            return ERROR;
        }
        
        // Receive packet
        if ((r = recvPacket(inpkt)) == 1) {
            return ERROR;
        } else if (r == 2) {
            i--;
            continue;
        }
        mvRetries = PKT_TRNSMAX;
        
        // Check for RRs
        switch (inpkt.type) {
        case PKT_TYPE_RR:
            if (inpkt.sequence == i && pkt[i].type == PKT_TYPE_CXN) {
                mvRemotePort = inpkt.size; // Extract new port number
                if ((sk = GetSocket(*(sockaddr_in *)&addr)) == -1) {
                    std::cerr << "GetSocket (" << __LINE__ << "): "
                              << strerror(errno) << std::endl;
                    return ERROR;
                }
                mvAddrLen = sizeof(mvAddr);
            } else if (inpkt.sequence == i && pkt[i].type == PKT_TYPE_CXN2) {
                // Apply new port changes
                mvSocket = sk;
                mvAddr = addr;
            } else if (inpkt.sequence != i) {
                // Incorrect sequence number: resend packet
                i--;
                continue;
            }
            break;
        case PKT_TYPE_REJ:
            if (inpkt.sequence <= i) {
                i = inpkt.sequence - 1;
            }
            break;
        }
    }
    
    if (mvRetries <= 0) {
        return ERROR;
    }
    
    mvSequence = 0;
    mvRetries = PKT_TRNSMAX;
    
    return RECV_PACKETS;
}