ssize_t dg_send_recv(int fd, const void *outbuff, size_t outbytes, void *inbuff, size_t inbytes, const SA *destaddr, socklen_t destlen) { ssize_t n; struct iovec iovsend[2], iovrecv[2]; if (rttinit == 0) { rtt_init(&rttinfo); /* first time we're called */ rttinit = 1; rtt_d_flags = 1; } sendhdr.seq++; msgsend.msg_name = destaddr; msgsend.msg_namelen = destlen; msgsend.msg_iov = iovsend; msgsend.msg_iovlen = 2; iovsend[0].iov_base = &sendhdr; iovsend[0].iov_len = sizeof(struct hdr); iovsend[1].iov_base = outbuff; iovsend[1].iov_len = outbytes; msgrecv.msg_name = NULL; msgrecv.msg_namelen = 0; msgrecv.msg_iov = iovrecv; msgrecv.msg_iovlen = 2; iovrecv[0].iov_base = &recvhdr; iovrecv[0].iov_len = sizeof(struct hdr); iovrecv[1].iov_base = inbuff; iovrecv[1].iov_len = inbytes; Signal(SIGALRM, sig_alrm); rtt_newpack(&rttinfo); /* initialize for this packet */ sendagain: sendhdr.ts = rtt_ts(&rttinfo); Sendmsg(fd, &msgsend, 0); alarm(rtt_start(&rttinfo)); /* calc timeout value & start timer */ if (sigsetjmp(jmpbuf, 1) != 0) { if (rtt_timeout(&rttinfo) < 0) { err_msg("dg_send_recv: no response from server, giving up"); rtt_init = 0; /* reinit in case we're called again */ errno = ETIMEDOUT; return -1; } goto sendagain; } do { n = Recvmsg(fd, &msgrecv, 0); } while (n < sizeof(struct hdr) || recvhdr.seq != sendhdr.seq); alarm(0); /* stop SIGALRM timer. */ /* calculate & store new RTT estimator value. */ rtt_stop(&rttinfo, rtt_ts(&rttinfo) - recvhdr.ts); return (n - sizeof(struct hdr)); /* return size of received datagram. */ }
struct hdr cli_recv(int fd, void *inbuff, size_t inbytes) { ssize_t n; struct iovec iovrecv[2]; struct rtt_info rttinfo; msgrecv.msg_name = NULL; msgrecv.msg_namelen = 0; msgrecv.msg_iov = iovrecv; msgrecv.msg_iovlen = 2; iovrecv[0].iov_base = &recvhdr; iovrecv[0].iov_len = sizeof(struct hdr); iovrecv[1].iov_base = inbuff; iovrecv[1].iov_len = inbytes; rttinfo.rtt_rto = CLI_TIMEOUT; //8 sec time out if (rttinit == 0) { rtt_init(&rttinfo); /* first time we're called */ rttinit = 1; rtt_d_flag = 1; } Signal(SIGALRM, sig_alrm); rtt_newpack(&rttinfo); /* initialize for this packet */ alarm(rtt_start(&rttinfo)/1000); /* calc timeout value & start timer */ //#ifdef RTT_DEBUG rtt_debug(&rttinfo); //#endif if (sigsetjmp(jmpbuf, 1) != 0) { err_msg("cli_recv: no response from server, giving up"); rttinit = 0; /* reinit in case we're called again */ errno = ETIMEDOUT; err_sys("[ERROR]: Timeout"); return recvhdr; } n = Recvmsg(fd, &msgrecv, 0); if (n < sizeof(struct hdr)){ err_sys("[ERROR]: Received packet incomplete"); } printf("Length: %d\n", (int)n); //printf("BUFFER: %s\n", (char *)iovrecv[1].iov_base); printf("SEQ NUM: %u\n", recvhdr.seq); printf("IS FIN: %u\n", recvhdr.fin); alarm(0); /* stop SIGALRM timer */ return(recvhdr); /* return size of received datagram */ }
void dg_echo(int sockfd, SA* pcliaddr, socklen_t clilen) { int n; char mesg[MAXLINE]; int on; char control[MAXLINE]; struct msghdr msg; struct cmsghdr* cmsg; struct iovec iov[1]; on = 1; Setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVRTHDR, &on, sizeof(on)); bzero(&msg, sizeof(msg)); iov[0].iov_base = mesg; msg.msg_name = pcliaddr; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_control = control; for (;;) { msg.msg_namelen = clilen; msg.msg_controllen = sizeof(control); iov[0].iov_len = MAXLINE; n = Recvmsg(sockfd, &msg, 0); for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_RTHDR) { inet6_srcrt_print(CMSG_DATA(cmsg)); Inet6_rth_reverse(CMSG_DATA(cmsg), CMSG_DATA(cmsg)); } } iov[0].iov_len = n; Sendmsg(sockfd, &msg, 0); } }
/* RETURNS ACK_NO */ int dg_recieve_ack( int fd ) { ssize_t n; struct iovec iovrecv[2]; char IPClient[20]; memset( &msgrecv, '\0', sizeof(msgrecv) ); memset( &recvhdr, '\0', sizeof(recvhdr) ); msgrecv.msg_name = NULL; msgrecv.msg_namelen = 0; msgrecv.msg_iov = iovrecv; msgrecv.msg_iovlen = 2; iovrecv[0].iov_base = &recvhdr; iovrecv[0].iov_len = sizeof(struct hdr); if( n = Recvmsg( fd, &msgrecv, 0) < 0 ) { printf("Error in RecvMsg!!\n"); printf("Error no : %d\n", errno ); exit(0); } if( recvhdr.ack_no == -3 ) { printf("Recieved a FIN-ACK from client..\n"); // struct itimerval value, ovalue, pvalue; // value.it_interval.tv_sec = 0; /* Zero seconds */ // value.it_interval.tv_usec = 0; /* Two hundred milliseconds */ // value.it_value.tv_sec = 0; /* Zero seconds */ // value.it_value.tv_usec = 0; /* Five hundred milliseconds */ // setitimer( ITIMER_REAL, &value, &ovalue ); return -3; } /* If we recieved the right packet ACKNOWLEDGEMENT, that is one which na was pointing to, we calculate RTT */ if( na == (recvhdr.ack_no - 1) ) { rtt_stop(&rttinfo, rtt_ts(&rttinfo) - recvhdr.ts); rtt_newpack( &rttinfo ); printf("Recieved an ACK-%d from client..\n", recvhdr.ack_no ); } printf( "Updating the reciever advertisement global variable with %d..\n", recvhdr.recv_window_advertisement ); recv_advertisement = recvhdr.recv_window_advertisement; update_na( recvhdr.ack_no ); current_ack = recvhdr.ack_no; if( prev_ack == current_ack ) { /* We got 3 DUP's */ dup_ack++; } else { dup_ack = 0; } /* swap fpr next ACK */ prev_ack = current_ack; return recvhdr.ack_no; }
ssize_t dg_send_recv(int fd, const void *outbuff, size_t outbytes, void *inbuff, size_t inbytes, const SA *destaddr, socklen_t destlen) { ssize_t n; struct iovec iovsend[2], iovrecv[2]; fd_set rset; int nsel, maxfdp1; struct timeval tv; if (rttinit == 0) { rtt_init(&rttinfo); /* first time we're called */ rttinit = 1; rtt_d_flag = 1; } sendhdr.seq++; msgsend.msg_name = destaddr; msgsend.msg_namelen = destlen; msgsend.msg_iov = iovsend; msgsend.msg_iovlen = 2; iovsend[0].iov_base = &sendhdr; iovsend[0].iov_len = sizeof(struct hdr); iovsend[1].iov_base = outbuff; iovsend[1].iov_len = outbytes; msgrecv.msg_name = NULL; msgrecv.msg_namelen = 0; msgrecv.msg_iov = iovrecv; msgrecv.msg_iovlen = 2; iovrecv[0].iov_base = &recvhdr; iovrecv[0].iov_len = sizeof(struct hdr); iovrecv[1].iov_base = inbuff; iovrecv[1].iov_len = inbytes; rtt_newpack(&rttinfo); /* initialize for this packet */ sendagain: #ifdef RTT_DEBUG fprintf(stderr, "send %4d: ", sendhdr.seq); #endif sendhdr.ts = rtt_ts(&rttinfo); Sendmsg(fd, &msgsend, 0); alarm(rtt_start(&rttinfo)); /* calc timeout value & start timer */ #ifdef RTT_DEBUG rtt_debug(&rttinfo); #endif tv.tv_sec = rtt_start(&rttinfo); tv.tv_usec = 0; maxfdp1 = fd + 1; again: FD_ZERO(&rset); FD_SET(fd, &rset); nsel = select(maxfdp1, &rset, NULL, NULL, &tv); if ((nsel == -1) || (errno == EINTR)) goto again; else if (nsel == -1) err_msg("select error"); else if (nsel == 0) { if (rtt_timeout(&rttinfo) < 0) { err_msg("dg_send_recv: no response from server, giving up"); rttinit = 0; /* reinit in case we're called again */ errno = ETIMEDOUT; return(-1); } #ifdef RTT_DEBUG err_msg("dg_send_recv: timeout, retransmitting"); #endif goto sendagain; } if (FD_ISSET(fd, &rset)) { do { n = Recvmsg(fd, &msgrecv, 0); #ifdef RTT_DEBUG fprintf(stderr, "recv %4d\n", recvhdr.seq); #endif } while (n < sizeof(struct hdr) || recvhdr.seq != sendhdr.seq); } /* 4calculate & store new RTT estimator values */ rtt_stop(&rttinfo, rtt_ts(&rttinfo) - recvhdr.ts); return(n - sizeof(struct hdr)); /* return size of received datagram */ }
/* analyze a file descriptor */ int filan_fd(int fd, FILE *outfile) { #if HAVE_STAT64 struct stat64 buf = {0}; #else struct stat buf = {0}; #endif /* !HAVE_STAT64 */ int result; Debug1("checking file descriptor %u", fd); #if HAVE_STAT64 result = Fstat64(fd, &buf); #else result = Fstat(fd, &buf); #endif /* !HAVE_STAT64 */ if (result < 0) { if (errno == EBADF) { Debug2("fstat(%d): %s", fd, strerror(errno)); } else { Warn2("fstat(%d): %s", fd, strerror(errno)); } return -1; } Debug2("fd %d is a %s", fd, getfiletypestring(buf.st_mode)); result = filan_stat(&buf, fd, fd, outfile); if (result >= 0) { /* even more dynamic info */ { /* see if data is available */ struct pollfd ufds; ufds.fd = fd; ufds.events = POLLIN|POLLPRI|POLLOUT #ifdef POLLRDNORM |POLLRDNORM #endif #ifdef POLLRDBAND |POLLRDBAND #endif |POLLWRNORM #ifdef POLLWRBAND |POLLWRBAND #endif #ifdef POLLMSG |POLLMSG #endif ; if (Poll(&ufds, 1, 0) < 0) { Warn4("poll({%d, %hd, %hd}, 1, 0): %s", ufds.fd, ufds.events, ufds.revents, strerror(errno)); } else { fputs("poll: ", outfile); if (ufds.revents & POLLIN) fputs("IN,", outfile); if (ufds.revents & POLLPRI) fputs("PRI,", outfile); if (ufds.revents & POLLOUT) fputs("OUT,", outfile); if (ufds.revents & POLLERR) fputs("ERR,", outfile); if (ufds.revents & POLLNVAL) fputs("NVAL,", outfile); #ifdef FIONREAD if (ufds.revents & POLLIN) { size_t sizet; if ((result = Ioctl(fd, FIONREAD, &sizet) >= 0)) { fprintf (outfile, "; FIONREAD="F_Zu, sizet); } } #endif /* defined(FIONREAD) */ #if _WITH_SOCKET && defined(MSG_DONTWAIT) if ((ufds.revents & POLLIN) && isasocket(fd)) { char _peername[SOCKADDR_MAX]; struct sockaddr *pa = (struct sockaddr *)_peername; struct msghdr msgh = {0}; char peekbuff[1]; /* [0] fails with some compilers */ #if HAVE_STRUCT_IOVEC struct iovec iovec; #endif char ctrlbuff[5120]; ssize_t bytes; fputs("; ", outfile); msgh.msg_name = pa; msgh.msg_namelen = sizeof(*pa); #if HAVE_STRUCT_IOVEC iovec.iov_base = peekbuff; iovec.iov_len = sizeof(peekbuff); msgh.msg_iov = &iovec; msgh.msg_iovlen = 1; #endif #if HAVE_STRUCT_MSGHDR_MSGCONTROL msgh.msg_control = ctrlbuff; #endif #if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN msgh.msg_controllen = sizeof(ctrlbuff); #endif #if HAVE_STRUCT_MSGHDR_MSGFLAGS msgh.msg_flags = 0; #endif if ((bytes = Recvmsg(fd, &msgh, MSG_PEEK|MSG_DONTWAIT)) < 0) { Warn1("recvmsg(): %s", strerror(errno)); } else { fprintf(outfile, "recvmsg="F_Zd", ", bytes); } } #endif /* _WITH_SOCKET && defined(MSG_DONTWAIT) */ } } } fputc('\n', outfile); return 0; }