Example #1
0
static PRInt32 _udt_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
		PRIntn flags, PRIntervalTime timeout) {
	///fprintf(stdout, "%s:%d\n", __func__, __LINE__);
	UDTSOCKET s = get_socket_from_fd(fd);

	// peek is not supported in udt
	if (PR_MSG_PEEK & flags) {
		PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
		return -1;
	}

	int rc = udt_recv(s, (char*)buf, amount, 0);

	if(rc < 0) {
		int udterrcode = udt_getlasterror_code();

		if (UDT_EASYNCRCV == udterrcode) {
			PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
		} else {
			PR_SetError(PR_IO_ERROR, 0);
		}
		return -1;
	}
	return rc;
}
Example #2
0
/* Main receiver function. State diagram: slide 8, chapter 5 */
void receiver() {
	 int ret;
	 int expected = 1;
	 Packet packet;

	 /* Try to receive a packet, check for network errors */
	 while (1) { 
		  ret = udt_recv(&packet, sizeof(packet), -1);
		  if (ret == NET_EOF)
			   break;
		  else if (ret == NET_SYSERR) {
			   fprintf(stderr, "Receiver: NET_SYSERR\n");
			   exit(1);
		  }
		  
		  /* At this point we have a valid packet. Check the sequence number. */
		  assert (ret == HEADERSIZE + packet.nbuffer);
		  /* printf("Receiver: Received packet #%d. ", packet.seqn); */
		  if (packet.seqn == expected) {
			   deliver_data(packet.buffer, packet.nbuffer);
			   receiver_acknowledge(expected);
			   expected++;
		  } else {
			   receiver_acknowledge(expected - 1);
		  }
	 }
}
Example #3
0
/* Attempts to get an ack. Timeout can be -1 (infinite) or any value >= 0.
   Returns -1 in case of timeout, otherwise the ACK sequence number. */
int get_ack(int timeout) {
	 ACKPacket ack;
	 int ret = udt_recv(&ack, sizeof(ACKPacket), timeout);
	 if (ret == NET_EOF) {
		  fprintf(stderr, "Sender: NET_EOF\n");
		  exit(1);
	 } else if (ret == NET_SYSERR) {
		  fprintf(stderr, "Sender: NET_SYSERR\n");
		  exit(1);
	 }
	 return ret == 0 ? -1 : ack.seqn;
}
Example #4
0
static PRInt32 _udt_read(PRFileDesc *fd, void *buf, PRInt32 amount) {
	///fprintf(stdout, "%s:%d\n", __func__, __LINE__);
	UDTSOCKET s = get_socket_from_fd(fd);
	int rc = udt_recv(s, (char*)buf, amount, 0);

	if(rc < 0) {
		int udterrcode = udt_getlasterror_code();

		if (UDT_EASYNCRCV == udterrcode) {
			PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
		} else {
			PR_SetError(PR_IO_ERROR, 0);
		}
		return -1;
	}
	return rc;
}
Example #5
0
static PRInt32 _udt_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
        PRIntn flags, PRIntervalTime timeout) {
    uint32_t dummy_data;
    PRUdtSocketDesc* desc = (PRUdtSocketDesc*)(fd->secret);
    if (desc->sign_cnt != desc->rd_cnt) {
        PR_Recv(desc->sock_pair0, (char*)&dummy_data, sizeof(dummy_data), 0, 0);
        PR_AtomicIncrement(&desc->rd_cnt);
    }
	// peek is not supported in udt
	if(PR_MSG_PEEK & flags)
		return PR_WOULD_BLOCK_ERROR;
    int rc = udt_recv(desc->udtfd, (char*)buf, amount, 0);
    if(rc < 0) {
        int udterrcode = udt_getErrorCode();
        if ((UDT_ERRECONNLOST == udterrcode) ||
           (UDT_ERRENOCONN == udterrcode)) {
            PR_Close(desc->sock_pair1);
            //rc = 0;
        }
    }
	return rc;
}
Example #6
0
static PRInt32 _udt_read(PRFileDesc *fd, void *buf, PRInt32 amount) {
    UDTSOCKET s = get_socket_from_fd(fd);
    uint32_t dummy_data;
    int rc = 0;
    PRUdtSocketDesc* desc = (PRUdtSocketDesc*)(fd->secret);
    if (desc->sign_cnt != desc->rd_cnt) {
        PR_Recv(desc->sock_pair0, (char*)&dummy_data, sizeof(dummy_data), 0, 0);
        PR_AtomicIncrement(&desc->rd_cnt);
    }
    rc = udt_recv(s, (char*)buf, amount, 0);
	if(rc < 0) {
	    int udterrcode = udt_getErrorCode();
	    if (UDT_ERRECONNLOST == udterrcode) {
	        rc = 0;
	        PR_Close(desc->sock_pair0);
	        PR_Close(desc->sock_pair1);
	    } else if (UDT_ERRENOCONN == udterrcode) {
	        rc = 0;
            PR_Close(desc->sock_pair0);
            PR_Close(desc->sock_pair1);
	    }
	}
    return rc;
}
Example #7
0
int main(int argc, char **argv ) {
	char ch;
	char buf[80];
	char sendline[MAXLINE];
	char recvline[MAXLINE];
	int udt;

	while ((ch = getopt(argc,argv,"p:R:P:h")) != -1) {
		switch(ch) {
		case 'p':
				local_port = atol(optarg);
			break;
		case 'R':
				 remote_addr = ntohl(inet_addr(optarg)); //!!! needs nhotl as udt requires host order!
			break;
		case 'P':
				remote_port = atol(optarg);
			break;
		case 'h':
			fprintf(stdout, PROGRAM_INFO);
			fprintf(stdout, "usage: udtdemo -p port -P port [-R address]\n\n");
			fprintf(stdout, "  p port    : local UDP socket binds to `port'\n" );
			fprintf(stdout, "  P port    : UDP datagrams will be sent to the remote `port'\n" );
			fprintf(stdout, "  R address : UDP datagrams will be sent to the remote host \n              as specified by `address' (an implicit is 127.0.0.1)\n\n" );
			exit(EXIT_SUCCESS);
		}
	}
	fprintf(stderr, PROGRAM_INFO);
	// Complain if something is missing or wrong.
	if (remote_addr == 0 || remote_port == 0 || local_port == 0) {
		fprintf(stderr, "Missing required arguments! Type '%s -h' for help.\n", PROGRAM);
		exit(EXIT_FAILURE);
	}


	fprintf(stderr, "Data channel from localhost:%d to %s:%d.\n", local_port, inet_ntop(AF_INET, &remote_addr, buf, 80), remote_port);
	fprintf(stderr, "Write data content, press ENTER to send the packet.\n");

	// It is important to init UDT!
	udt = udt_init(local_port);

	fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);	// make stdin reading non-clocking

	fd_set readfds;
	FD_ZERO(&readfds);
	FD_SET(udt, &readfds);
	FD_SET(STDIN_FILENO, &readfds);
	while (select(udt+1, &readfds, NULL, NULL, NULL)) {
		if (FD_ISSET(STDIN_FILENO, &readfds) && fgets(sendline, MAXLINE, stdin)>0) { // we have read a new line to send
			if (!udt_send(udt, remote_addr, remote_port, sendline, strlen(sendline))) {
				perror("udtdemo: ");	// some error
			}
		}
		if (FD_ISSET(udt, &readfds)) {	// We have a new message to print
			int n = udt_recv(udt, recvline, MAXLINE, NULL, NULL);
			recvline[n] = 0;
			fputs(recvline, stdout);
		}
		// and again!
		FD_ZERO(&readfds);
		FD_SET(udt, &readfds);
		FD_SET(STDIN_FILENO, &readfds);
	}
	return EXIT_SUCCESS;
}
Example #8
0
bool process(params_t* args)
{
    ipk_sock_t udt = IPK_SOCK_INVALID;
    rdt_t* rdt = NULL;

#ifndef _WIN32
    if (!ipk_fd_block_mode(STDIN_FILENO, false)) {
        return false;
    }
#endif

    udt = udt_init(args->src_port);
    if (!udt_connect(udt, args->dst_port)) {
        goto return_false;
    }

    rdt = rdt_new();
    if (!rdt) {
        goto return_false;
    }

    if (!rdt_client_start(rdt)) {
        goto return_false;
    }

    bool eof = false;
    char buf[BUF_MAXLEN];
    char rcvbuf[UDT_PACKET_MAXLEN];
    char sndbuf[UDT_PACKET_MAXLEN];
    size_t nbuf = 0;
    size_t nrcvbuf = 0;
    size_t nsndbuf = 0;

    struct timeval tv;
    tv.tv_sec = 0;
    tv.tv_usec = 100000;

#ifdef _WIN32
    int nfds = 0; // ignored on win32
#else
    int nfds = max(STDIN_FILENO, udt) + 1;
#endif
    fd_set rfds, wfds;

    while (!_terminate) {
        FD_ZERO(&rfds);
        FD_ZERO(&wfds);

        if (nsndbuf == 0) {
            nsndbuf = _countof(sndbuf);
            rdt_client_step(rdt, rcvbuf, nrcvbuf, sndbuf, &nsndbuf);
        }
        else {
            rdt_client_step(rdt, rcvbuf, nrcvbuf, NULL, NULL);
        }

        nrcvbuf = 0;
        FD_SET(udt, &rfds);

        if (nsndbuf > 0) {
            FD_SET(udt, &wfds);
        }

#ifndef _WIN32
        if (!eof && nbuf < _countof(buf)) {
            FD_SET(STDIN_FILENO, &rfds);
        }
#endif

        if (nbuf > 0 && rdt_data_write(rdt, buf, nbuf)) {
            nbuf = 0;
        }
        else if (eof) {
            if (rdt_client_done(rdt))
                break;
        }

        int numfd = select(nfds, &rfds, &wfds, NULL, &tv);
        if (numfd == -1) {
            ipk_sock_perror(ipk_sock_errno);
        }
        else if (numfd == 0) {
            continue;
        }
        else {
#ifndef _WIN32
            if (FD_ISSET(STDIN_FILENO, &rfds)) {
#else
            if (!eof) {
#endif
                size_t erecv = _countof(buf) - nbuf;
                size_t nrecv = fread(buf + nbuf, sizeof(char), erecv, stdin);
                _ipk_verbose_log("Readed %zu from stdin.", nrecv);

                nbuf += nrecv;
                if (nrecv != erecv) {
                    if (feof(stdin)) {
                        eof = true;
                    }
                    else if (ferror(stdin) && !ipk_sock_is_recoverable(errno)) {
                        ipk_perror(errno);
                        // send RST
                    }
                }
            }

            if (FD_ISSET(udt, &wfds)) {
                int nsnd = udt_send(udt, sndbuf, nsndbuf);
                if (nsnd == -1) {
                    ipk_sock_perror(ipk_sock_errno);
                    goto return_false;
                }
                else if (nsnd > 0) {
                    nsndbuf = 0;

                    sndbuf[nsnd] = '\0';
                    _ipk_debug_log("#%x <<<\n%s", udt, sndbuf);
                    _ipk_debug_log("#%x /<<<", udt);
                }
                else {
                    // send again
                }
            }

            if (FD_ISSET(udt, &rfds)) {
                int nrcv = udt_recv(udt, rcvbuf, _countof(rcvbuf));
                if (nrcv == -1) {
                    ipk_sock_perror(ipk_sock_errno);
                    goto return_false;
                }
                else if (nrcv > 0) {
                    nrcvbuf = nrcv;

                    rcvbuf[nrcv] = '\0';
                    _ipk_debug_log("#%x >>>\n%s", udt, rcvbuf);
                    _ipk_debug_log("#%x />>>", udt);
                }
                else {
                    // read again
                }
            }
        }
    }

    rdt_dispose(rdt);
    ipk_sock_close(udt);
    return true;

return_false:
    rdt_dispose(rdt);
    ipk_sock_close(udt);
    return false;
}

int main(int argc, char* argv[])
{
    params_t params;
    memset(&params, '\0', sizeof(params_t));

    setlocale(LC_ALL, "");
    ipk_set_log_func(&mylog);
    ipk_set_log_level(1);

    if (!parseargs(argc, argv, &params)) {
        _ipk_error_log("%s", "Chyba: nebyl zadan povinny parametr.");
        fprintf(stdout, "%s", "Synopsis: rdtclient -s source_port -d dest_port\n");
        return EXIT_FAILURE;
    }

    ipk_set_log_level(params.verbose_lvl);

    if (params.action == ACT_HELP) {
        fprintf(stdout, "%s",
                "Spolehliva komunikace, projekt c. 3 pro predmet IPK.\n"
                "Autor: Radek Sevcik, [email protected]\n"
                "\n"
                "Synopsis: rdtclient -s source_port -d dest_port\n"
                "\n"
                "Parametry:\n"
                "  -h\t\t\tVypise napovedu.\n"
                "  -s source_port\tNasloucha na portu source_port.\n"
                "  -d dest_port\t\tPripoji se na port dest_port.\n");
        return EXIT_SUCCESS;
    }

    // sigint (ctrl+c), sigterm
#ifdef _WIN32
    if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)&on_console_handler, true)) {
        ipk_perror_win(GetLastError());
        return EXIT_FAILURE;
    }
#else
    if (SIG_ERR == signal(SIGINT, &on_signal)) {
        ipk_perror(errno);
        return EXIT_FAILURE;
    }
    if (SIG_ERR == signal(SIGTERM, &on_signal)) {
        ipk_perror(errno);
        return EXIT_FAILURE;
    }
#endif

    if (!ipk_sock_init()) {
        return EXIT_FAILURE;
    }

    if (0 != atexit(&cleanup)) {
        _ipk_error_log("%s", "Chyba: nedostatek pameti");
        return EXIT_FAILURE;
    }

    return process(&params)
           ? EXIT_SUCCESS : EXIT_FAILURE;
}