void disconnect(char *src_ip, char *dst_ip, char *path, int recv_port){
    // build fin packet
    char buf[10000];
    char ack_buf[10000];
    size_t len, sent, recv_size;
    struct iphdr *iph;
    struct tcphdr *tcph;
    if (passive_fin == 0){
        len = build_fin_packet(buf, 2000, src_ip, dst_ip, recv_port, seq_num, expected_seq);
        sent = sendto(sock_send, buf, len, 0, (struct sockaddr *)&sin_send, sizeof(sin_send));
        printf("FIN packet sent, size: %u\n", sent);
    }
    // receive ack 
    while (connected == 1){
        recv_size = recv(sock_recv, buf, sizeof(buf), 0);
        if (recv_size < IP_HDR_SIZE + TCP_HDR_SIZE) {
            continue;
        }
        iph = (struct iphdr *)buf;
        tcph = (struct tcphdr *)(buf + IP_HDR_SIZE);
        if (iph->saddr != inet_addr(dst_ip) && tcph->source != htons(HTTP_PORT) && ntohl(tcph->dest) != recv_port){
            continue;
        }
        if (tcph->fin == 1 && tcph->ack == 1){
            seq_num += 1;
            len = build_ack(ack_buf, buf, recv_port, src_ip, dst_ip, seq_num);
            sendto(sock_send, ack_buf, len, 0, (struct sockaddr *)&sin_send, sizeof(sin_send));
            return;
        }
    }
}
Esempio n. 2
0
void handle_incoming_msgs(Receiver * receiver,
                          LLnode ** outgoing_frames_head_ptr)
{
    //TODO: Suggested steps for handling incoming frames
    //    1) Dequeue the Frame from the sender->input_framelist_head
    //    2) Convert the char * buffer to a Frame data type
    //    3) Check whether the frame is corrupted
    //    4) Check whether the frame is for this receiver
    //    5) Do sliding window protocol for sender/receiver pair

    int incoming_msgs_length = ll_get_length(receiver->input_framelist_head);
    while (incoming_msgs_length > 0)
    {
        //Pop a node off the front of the link list and update the count
        LLnode * ll_inmsg_node = ll_pop_node(&receiver->input_framelist_head);
        incoming_msgs_length = ll_get_length(receiver->input_framelist_head);

        //DUMMY CODE: Print the raw_char_buf
        //NOTE: You should not blindly print messages!
        //      Ask yourself: Is this message really for me?
        //                    Is this message corrupted?
        //                    Is this an old, retransmitted message?           
        char * raw_char_buf = (char *) ll_inmsg_node->value;
        
	if (chksum_all(raw_char_buf))
	{
	    fprintf(stderr, "chksum error\n");
	    free(raw_char_buf);
            free(ll_inmsg_node);
	    continue;
	}
        Frame * inframe = convert_char_to_frame(raw_char_buf);
	if (inframe->src == receiver->send_id)
	{
	    if (inframe->dst == receiver->recv_id)
	    {
		Frame * outframe;
		char* buf;

		outframe = build_ack(receiver, inframe);

		buf = add_chksum(outframe);
		print_receiver(receiver);
		ll_append_node(outgoing_frames_head_ptr, buf);
		free(outframe);
	    }
	}

	//free(inframe);
	free(raw_char_buf);
        free(ll_inmsg_node);
    }
}
void receive_data(char *src_ip, char *dst_ip, char *path, int recv_port){
    // build syn packet
    char buf[10000];
    char ack_buf[10000];
    size_t len, recv_size, data_size;
    struct iphdr *iph;
    struct tcphdr *tcph;
    int first = 1;
    while (all_get == 0){
        memset(buf, 0, sizeof(buf));
        recv_size = recv(sock_recv, buf, sizeof(buf), 0);
        if (recv_size < IP_HDR_SIZE + TCP_HDR_SIZE) {
            continue;
        }
        iph = (struct iphdr *)buf;
        tcph = (struct tcphdr *)(buf + IP_HDR_SIZE);
        if (iph->saddr != inet_addr(dst_ip) && tcph->source != htons(HTTP_PORT) && ntohl(tcph->dest) != recv_port){
            continue;
        }
        data_size = (recv_size - IP_HDR_SIZE - TCP_HDR_SIZE);
        if (tcph->ack == 1 && tcph->syn == 0 && tcph->fin == 0 && tcph->rst == 0) {
            if (ntohl(tcph->seq) > expected_seq){
                continue;
            }
            if (ntohl(tcph->seq) == expected_seq){
                if (first == 1){
                    int doc_size = proc_http(buf+IP_HDR_SIZE+TCP_HDR_SIZE, data_size);
                    last_seq = ntohl(tcph->seq) + doc_size;
                    printf("doc size: %d\n", doc_size);
                    first = 0;
                }
                expected_seq += data_size;
                write(fd, buf+IP_HDR_SIZE+TCP_HDR_SIZE, data_size);
            }
            len = build_ack(ack_buf, buf, recv_port, src_ip, dst_ip, seq_num);
            sendto(sock_send, ack_buf, len, 0, (struct sockaddr *)&sin_send, sizeof(sin_send));
        }
        if(ntohl(tcph->seq) + data_size == last_seq){
            printf("All data received\n");
            return;
        }
        if (tcph->fin == 1) {
            passive_fin = 1;
        }
    }
}
void conn_server(char *src_ip, char *dst_ip, char *path, int recv_port){
    // build syn packet
    char buf[10000];
    char ack_buf[10000];
    size_t len, sent, recv_size, http_req_size;
    struct iphdr *iph;
    struct tcphdr *tcph;
    len = build_syn_packet(buf, 2000, src_ip, dst_ip, recv_port, start_seq_num);
    sent = sendto(sock_send, buf, len, 0, (struct sockaddr *)&sin_send, sizeof(sin_send));
    printf("SYN packet sent, size: %u\n", sent);
    // receive ack 
    while (connected != 1){
        recv_size = recv(sock_recv, buf, sizeof(buf), 0);
        if (recv_size < IP_HDR_SIZE + TCP_HDR_SIZE) {
            continue;
        }
        iph = (struct iphdr *)buf;
        tcph = (struct tcphdr *)(buf + IP_HDR_SIZE);
        if (iph->saddr != inet_addr(dst_ip) && tcph->source != htons(HTTP_PORT) && ntohl(tcph->dest) != recv_port){
            continue;
        }
        printf("Received: %u\n", recv_size);
        if (tcph->syn == 1 && tcph->ack == 1){
            seq_num = start_seq_num + 1;
            len = build_ack(ack_buf, buf, recv_port, src_ip, dst_ip, seq_num);
            sendto(sock_send, ack_buf, len, 0, (struct sockaddr *)&sin_send, sizeof(sin_send));
            printf("Ack replied for connection\n");
            len = build_http_req(ack_buf, buf, 10000, src_ip, dst_ip, recv_port, path, seq_num);
            http_req_size = len - IP_HDR_SIZE - TCP_HDR_SIZE;
            sendto(sock_send, ack_buf, len, 0, (struct sockaddr *)&sin_send, sizeof(sin_send));
            continue;
        }
        if (tcph->ack == 1) {
            if (ntohl(tcph->ack_seq) == seq_num + http_req_size){
                seq_num += http_req_size;
                expected_seq = ntohl(tcph->seq);
                connected = 1;
            }
        }
    }
}
Esempio n. 5
0
/* this is the main function with the loops and modes */
void shoot(char *buf, int buff_size)
{
	struct timespec sleep_ms_s, sleep_rem;
	int ret, cseqtmp, rand_tmp;
	char buf2[BUFSIZE], buf3[BUFSIZE], lport_str[LPORT_STR_LEN];

	/* delays.retryAfter = DEFAULT_TIMEOUT; */
	if (transport == SIP_UDP_TRANSPORT) {
		delays.retryAfter = timer_t1;
	}
	else {
		delays.retryAfter = timer_final;
	}
	inv_trans = 0;
	cseq_counter = 1;
	usrlocstep = REG_REP;

	/* initalize local vars */
	cdata.dontsend=cdata.dontrecv=counters.retrans_r_c=counters.retrans_s_c= 0;
	delays.big_delay=counters.send_counter=counters.run= 0;
	timers.delaytime.tv_sec = 0;
	timers.delaytime.tv_usec = 0;
	usern = NULL;
	/* initialize local arrays */
	memset(buf2, 0, BUFSIZE);
	memset(buf3, 0, BUFSIZE);
	memset(lport_str, 0, LPORT_STR_LEN);

	cdata.csock = cdata.usock = -1;
	cdata.connected = 0;
	cdata.buf_tmp = NULL;
	cdata.buf_tmp_size = 0;

	memset(&(timers.sendtime), 0, sizeof(timers.sendtime));
	memset(&(timers.recvtime), 0, sizeof(timers.recvtime));
	memset(&(timers.firstsendt), 0, sizeof(timers.firstsendt));
	memset(&(timers.starttime), 0, sizeof(timers.starttime));
	memset(&(timers.delaytime), 0, sizeof(timers.delaytime));

	req = buf;
	rep = buf2;
	rec = buf3;

	create_sockets(&cdata);

	if (sleep_ms != 0) {
		if (sleep_ms == -2) {
			rand_tmp = rand();
			sleep_ms_s.tv_sec = rand_tmp / 1000;
			sleep_ms_s.tv_nsec = (rand_tmp % 1000) * 1000000;
		}
		else {
			sleep_ms_s.tv_sec = sleep_ms / 1000;
			sleep_ms_s.tv_nsec = (sleep_ms % 1000) * 1000000;
		}
	}

	if (replace_b == 1){
		replace_string(req, "$dsthost$", domainname);
		replace_string(req, "$srchost$", fqdn);
		sprintf(lport_str, "%i", lport);
		replace_string(req, "$port$", lport_str);
		if (username)
			replace_string(req, "$user$", username);
	}
	if (replace_str)
		replace_strings(req, replace_str);

	/* set all regular expression to simplfy the result code indetification */
	regcomp(&(regexps.replyexp), "^SIP/[0-9]\\.[0-9] [1-6][0-9][0-9]", 
		REG_EXTENDED|REG_NOSUB|REG_ICASE); 
	regcomp(&(regexps.proexp), "^SIP/[0-9]\\.[0-9] 1[0-9][0-9] ", 
		REG_EXTENDED|REG_NOSUB|REG_ICASE); 
	regcomp(&(regexps.okexp), "^SIP/[0-9]\\.[0-9] 2[0-9][0-9] ", 
		REG_EXTENDED|REG_NOSUB|REG_ICASE); 
	regcomp(&(regexps.redexp), "^SIP/[0-9]\\.[0-9] 3[0-9][0-9] ", 
		REG_EXTENDED|REG_NOSUB|REG_ICASE);
	regcomp(&(regexps.authexp), "^SIP/[0-9]\\.[0-9] 40[17] ", 
		REG_EXTENDED|REG_NOSUB|REG_ICASE);
	regcomp(&(regexps.errexp), "^SIP/[0-9]\\.[0-9] 4[0-9][0-9] ", 
		REG_EXTENDED|REG_NOSUB|REG_ICASE); 
	regcomp(&(regexps.tmhexp), "^SIP/[0-9]\\.[0-9] 483 ", 
		REG_EXTENDED|REG_NOSUB|REG_ICASE); 

	if (username) {
		if (nameend > 0) {
			usern = str_alloc(strlen(username) + 12);
			create_usern(usern, username, namebeg);
		}
		else {
			if (*(username + strlen(username) - 1) != '@') {
				usern = str_alloc(strlen(username) + 2);
				create_usern(usern, username, -1);
			}
			else {
				usern = username;
			}
		}
	}

	if (usrloc == 1||invite == 1||message == 1){
		/* calculate the number of required steps and create initial mes */
		if (usrloc == 1) {
			create_msg(REQ_REG, req, NULL, usern, cseq_counter);
			usrlocstep=REG_REP;
		}
		else if (invite == 1) {
			create_msg(REQ_INV, req, rep, usern, cseq_counter);
			inv_trans = 1;
			usrlocstep=INV_RECV;
		}
		else {
			create_msg(REQ_MES, req, rep, usern, cseq_counter);
			if (mes_body)
				usrlocstep=MES_OK_RECV;
			else
				usrlocstep=MES_RECV;
		}
	}
	else if (trace == 1){
		/* for trace we need some spezial initis */
		namebeg=0;
		create_msg(REQ_OPT, req, NULL, usern, cseq_counter);
		set_maxforw(req, namebeg);
	}
	else if (flood == 1){
		if (nameend<=0) nameend=INT_MAX;
		namebeg=1;
		create_msg(REQ_FLOOD, req, NULL, usern, cseq_counter);
	}
	else if (randtrash == 1){
		counters.randretrys=0;
		namebeg=1;
		create_msg(REQ_RAND, req, NULL, usern, cseq_counter);
		nameend=(int)strlen(req);
		if (trashchar == 1){
			if (trashchar < nameend)
				nameend=trashchar;
			else
				fprintf(stderr, "warning: number of trashed chars to big. setting to "
					"request length\n");
		}
		trash_random(req);
	}
	else {
		/* for none of the modes we also need some inits */
		if (file_b == 0) {
			namebeg=1;
			create_msg(REQ_OPT, req, NULL, usern, cseq_counter);
		}
		else {
			if (STRNCASECMP(req, INV_STR, INV_STR_LEN) == 0) {
				inv_trans = 1;
			}
			if(via_ins == 1)
				add_via(req);
		}
		/* delays.retryAfter = delays.retryAfter / 10; */
		if(maxforw!=-1)
			set_maxforw(req, maxforw);
	}

	cdata.connected = set_target(&(cdata.adr), address, rport, cdata.csock, cdata.connected);

	/* here we go until someone decides to exit */
	while(1) {
		before_sending();

		if (sleep_ms == -2) {
			rand_tmp = rand();
			sleep_ms_s.tv_sec = rand_tmp / 1000;
			sleep_ms_s.tv_nsec = (rand_tmp % 1000) * 1000;
		}
		if (sleep_ms != 0) {
			dbg("sleeping for %li s + %li ns\n", sleep_ms_s.tv_sec, sleep_ms_s.tv_nsec);
			nanosleep(&sleep_ms_s, &sleep_rem);
		}

		send_message(req, &cdata, &counters, &timers);

		/* in flood we are only interested in sending so skip the rest */
		if (flood == 0) {
			ret = recv_message(rec, BUFSIZE, inv_trans, &delays, &timers,
						&counters, &cdata, &regexps);
			if(ret > 0)
			{
				if (usrlocstep == INV_OK_RECV) {
					swap_ptr(&rep, &req);
				}
				/* send ACK for non-provisional reply on INVITE */
				if ((STRNCASECMP(req, "INVITE", 6)==0) && 
						(regexec(&(regexps.replyexp), rec, 0, 0, 0) == REG_NOERROR) && 
						(regexec(&(regexps.proexp), rec, 0, 0, 0) == REG_NOMATCH)) { 
					build_ack(req, rec, rep, &regexps);
					cdata.dontsend = 0;
					inv_trans = 0;
					/* lets fire the ACK to the server */
					send_message(rep, &cdata, &counters, &timers);
					inv_trans = 1;
				}
				/* check for old CSeq => ignore retransmission */
				cseqtmp = cseq(rec);
				if ((0 < cseqtmp) && (cseqtmp < cseq_counter)) {
					if (verbose>0) {
						printf("ignoring retransmission\n");
					}
					counters.retrans_r_c++;
					cdata.dontsend = 1;
					continue;
					}
				else if (regexec(&(regexps.authexp), rec, 0, 0, 0) == REG_NOERROR) {
					if (!username && !auth_username) {
						if (timing > 0) {
							timing--;
							if (timing == 0) {
								if (counters.run == 0) {
									counters.run++;
								}
								printf("%.3f/%.3f/%.3f ms\n", delays.small_delay, delays.all_delay / counters.run, delays.big_delay);
								exit_code(0, __PRETTY_FUNCTION__, NULL);
							}
							counters.run++;
							new_transaction(req, rep);
							delays.retryAfter = timer_t1;
							continue;
						}
						fprintf(stderr, "%s\nerror: received 40[17] but cannot "
							"authentication without a username or auth username\n", rec);
						log_message(req);
						exit_code(2, __PRETTY_FUNCTION__, "missing username for authentication");
					}
					/* prevents a strange error */
					regcomp(&(regexps.authexp), "^SIP/[0-9]\\.[0-9] 40[17] ", REG_EXTENDED|REG_NOSUB|REG_ICASE);
					insert_auth(req, rec);
					if (verbose > 2)
						printf("\nreceived:\n%s\n", rec);
					new_transaction(req, rep);
					continue;
				} /* if auth...*/
				/* lets see if received a redirect */
				if (redirects == 1 && regexec(&(regexps.redexp), rec, 0, 0, 0) == REG_NOERROR) {
					handle_3xx(&(cdata.adr));
				} /* if redircts... */
				else if (trace == 1) {
					trace_reply();
				} /* if trace ... */
				else if (usrloc == 1||invite == 1||message == 1) {
					handle_usrloc();
				}
				else if (randtrash == 1) {
					handle_randtrash();
				}
				else {
					handle_default();
				} /* redirect, auth, and modes */
			} /* ret > 0 */
			else if (ret == -1) { // we did not got anything back, send again
				/* no re-transmission on reliable transports */
				if (transport != SIP_UDP_TRANSPORT) {
					cdata.dontsend = 1;
				}
				continue;
			}
			else if (ret == -2) { // we received non-matching ICMP
				cdata.dontsend = 1;
				continue;
			}
			else {
				if (usrloc == 1) {
					printf("failed\n");
				}
				perror("socket error");
				exit_code(3, __PRETTY_FUNCTION__, "internal socket error");
			}
		} /* !flood */
		else {
			if (counters.send_counter == 1) {
					memcpy(&(timers.firstsendt), &(timers.sendtime), sizeof(struct timeval));
			}
			if (namebeg==nameend) {
				printf("flood end reached\n");
				printf("it took %.3f ms seconds to send %i request.\n", 
						deltaT(&(timers.firstsendt), &(timers.sendtime)), namebeg);
				printf("we sent %f requests per second.\n", 
						(namebeg/(deltaT(&(timers.firstsendt), &(timers.sendtime)))*1000));
				exit_code(0, __PRETTY_FUNCTION__, NULL);
			}
			namebeg++;
			cseq_counter++;
			create_msg(REQ_FLOOD, req, NULL, usern, cseq_counter);
		}
	} /* while 1 */

	/* this should never happen any more... */
	if (randtrash == 1) {
		exit_code(0, __PRETTY_FUNCTION__, NULL);
	}
	printf("** give up retransmissioning....\n");
	if (counters.retrans_r_c>0 && (verbose > 1)) {
		printf("%i retransmissions received during test\n", counters.retrans_r_c);
	}
	if (counters.retrans_s_c>0 && (verbose > 1)) {
		printf("sent %i retransmissions during test\n", counters.retrans_s_c);
	}
	exit_code(3, __PRETTY_FUNCTION__, "got outside of endless messaging loop");
}