Exemplo n.º 1
0
// Connect to the server, and send the first datagram
void initiate_tx(void) {
  sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
  if (conn->is_local) {
    set_dontroute(sockfd);	
  }

  // Bind to port 0
  Bind(sockfd, conn->cli_sa, (socklen_t)sizeof(SA));

  struct sockaddr_in sin;
  UINT addrlen = sizeof(SA);

  // Fetch port number at which kernel bound this socket.
  Getsockname(sockfd, (SA *)&sin, &addrlen);
  cliport = ntohs(sin.sin_port);
  INFO("Client's ephemeral Port Number: %d\n", cliport);

  // Connect to the server.
  Connect(sockfd, conn->serv_sa, sizeof(SA));

  // TODO
  // Do we need getpeername here?
  
  // Start a timer here to re-send the file name till we receive an
  // ACK.

  struct timeval timeout;
  timeout.tv_sec = 3;
  timeout.tv_usec = 0;

  fdset_init(&fds, timeout, ack_timeout);

  fdset_add(&fds, &fds.rev, sockfd, &sockfd, send_file);
  fdset_add(&fds, &fds.exev, sockfd, &sockfd, handle_tx_error);

  // Send the packet to the server
  INFO("Trying to send the SYN packet to the Server with the file name%s\n", "");
  send_filename_pkt();

  int r = fdset_poll2(&fds);
  if (r < 0) {
    perror("select");
    ASSERT(errno != EINTR);
    exit(1);
  }
}
Exemplo n.º 2
0
void
server_loop(void) {
  struct timeval timeout;
  int r;

  VERBOSE("server_loop()%s\n", "");

  timeout.tv_sec = 10; // FIXME when we know better
  timeout.tv_usec = 0;

  fdset_init(&fds, timeout, NULL);

  fdset_add(&fds, &fds.rev,  s.sockfd, &s.sockfd, on_recv);
  fdset_add(&fds, &fds.exev, s.sockfd, &s.sockfd, on_error);

  r = fdset_poll(&fds, &timeout, on_recv_timedout);
  if (r < 0) {
    perror("select");
    ASSERT(errno != EINTR);
    exit(1);
  }
}
Exemplo n.º 3
0
static int tcp_event_accept(tcp_context_t *tcp, unsigned i)
{
	/* Accept client. */
	int fd = tcp->set.pfd[i].fd;
	int client = tcp_accept(fd);
	if (client >= 0) {
		/* Assign to fdset. */
		int next_id = fdset_add(&tcp->set, client, POLLIN, NULL);
		if (next_id < 0) {
			close(client);
			return next_id; /* Contains errno. */
		}

		/* Update watchdog timer. */
		rcu_read_lock();
		fdset_set_watchdog(&tcp->set, next_id, conf()->max_conn_hs);
		rcu_read_unlock();
	}

	return KNOT_EOK;
}
Exemplo n.º 4
0
void send_file(void *opaque) {
  int portno;
  struct sockaddr sa;
  struct sockaddr_in *si = (struct sockaddr_in *) &sa;
  socklen_t sa_sz = sizeof(sa);
  
  packet_t pkt;
  int r;
  r = perhaps_recvfrom(sockfd, (void*)&pkt, sizeof(pkt), 0, &sa, &sa_sz);

  if (r < 0) {
    if (errno == EINTR || errno == ECONNREFUSED) {
      // We return from this function in the hope that the next time
      // 'sockfd' is read ready, we will be invoked again.
      return;
    } else {
      perror("recvfrom");
      exit(1);
    }
  }
  packet_ntoh(&pkt, &pkt);

  pkt.data[pkt.datalen] = '\0';
  sscanf(pkt.data, "%d", &portno);
  const char *serverIP = sa_data_str(&sa);

  INFO("Server endpoints {1} [%s:%d] & {2} [%s:%d]\n", serverIP, ntohs(si->sin_port), serverIP, portno);

  /*
  // Disconnect port association.
  sa.sa_family = AF_UNSPEC;
  Connect(sockfd, &sa, sizeof(SA));

  // Bind to the port we were originally bound to, and connect this
  // socket to the new port number that the server sent us.
  struct sockaddr cli_sa;
  struct sockaddr_in *cli_si = (struct sockaddr_in*)&cli_sa;
  memset(&cli_sa, 0, sizeof(cli_sa));
  memcpy(&cli_sa, conn->cli_sa, sizeof(struct sockaddr));
  cli_si->sin_port = htons(cliport);
  Bind(sockfd, &cli_sa, (socklen_t)sizeof(struct sockaddr_in));
  */

  // We open a new socket and dup2() since nothing else seems to be
  // working on both Linux as well as Solaris.
  int new_sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
  dup2(new_sockfd, sockfd);
  if (conn->is_local) {
    set_dontroute(sockfd);
  }

  // Bind to the port we were originally bound to, and connect this
  // socket to the new port number that the server sent us.
  struct sockaddr_in cli_si;
  memset(&cli_si, 0, sizeof(cli_si));
  memcpy(&cli_si, conn->cli_sa, sizeof(struct sockaddr));
  cli_si.sin_port = htons(cliport);
  Bind(sockfd, (struct sockaddr*)&cli_si, (socklen_t)sizeof(struct sockaddr_in));

  sa = *(conn->serv_sa);
  si->sin_port = htons(portno);
  Connect(sockfd, &sa, sizeof(SA));

  // Send an ACK to the server.
  pkt.flags = FLAG_ACK;
  pkt.ack   = 1;
  pkt.rwinsz = cargs->sw_size;
  ++pkt.seq;
  pkt.datalen = 0;
  memset(pkt.data, 0, sizeof(pkt.data));
  sprintf(pkt.data, "ACK:%d, RWINSZ: %d", pkt.ack, pkt.rwinsz);

  INFO("Sending %d bytes of data to the server\n", sizeof(pkt));
  send_packet(&pkt);

  // Receive data from the socket till a packet with the FLAG_FIN flag
  // is received.
 
  if (pthread_create(&tid, NULL, (void *) (&consume_packets), (void *) (&rwin)) < 0) {
      err_sys("Could not spawn the consumer thread to read packets");
  }

  while (1) {
      VERBOSE("Waiting on recv(2)...%s\n", "");
      int r = recv_packet(&pkt);
      if (r < 0) {
        // Handle EINTR.
        if (errno == EINTR) {
          // Go back to waiting for a packet.
          continue;
        } else {
          if (errno == ECONNREFUSED) {
            INFO("http://memegenerator.net/instance/29609574%s\n", "");
          }
          perror("recv");
          exit(1);
        }
      }
      INFO("Received packet with SEQ#: %u\n", pkt.seq);
      packet_t *ack_pkt = rwindow_received_packet(&rwin, &pkt);
      INFO("ACK Packet will be sent with ACK: %u, Window Size: %d\n", ack_pkt->ack, ack_pkt->rwinsz);

      send_packet(ack_pkt);
      
      if (rwindow_received_all(&rwin)) {
          fdset_remove(&fds, &fds.rev, sockfd);
          fds.timeout_cb = fin_timeout;
          fdset_add(&fds, &fds.rev, sockfd, &sockfd, resend_fin_pkt);
          fds.timeout.tv_sec = 60;
          fds.timeout.tv_usec = 0;
          
          time_av_ms = 60*1000;
          at_select_ms = current_time_in_ms();
          INFO("Entering the TIME_WAIT state%s\n", "");
          INFO("File Transfer completed in %d sec\n", current_time_in_ms() / 1000);
          return;
      } 

      free(ack_pkt);
      ack_pkt = NULL;
  } // while (1)
}
Exemplo n.º 5
0
int main(int argc, char *argv[])
{
	plan(12);

	/* 1. Create fdset. */
	fdset_t set;
	int ret = fdset_init(&set, 32);
	is_int(0, ret, "fdset: init");

	/* 2. Create pipe. */
	int fds[2], tmpfds[2];
	ret = pipe(fds);
	ok(ret >= 0, "fdset: pipe() works");
	ret = pipe(tmpfds);
	ok(ret >= 0, "fdset: 2nd pipe() works");

	/* 3. Add fd to set. */
	ret = fdset_add(&set, fds[0], POLLIN, NULL);
	is_int(0, ret, "fdset: add to set works");
	fdset_add(&set, tmpfds[0], POLLIN, NULL);

	/* Schedule write. */
	struct timeval ts, te;
	gettimeofday(&ts, 0);
	pthread_t t;
	pthread_create(&t, 0, thr_action, &fds[1]);

	/* 4. Watch fdset. */
	int nfds = poll(set.pfd, set.n, 60 * 1000);
	gettimeofday(&te, 0);
	size_t diff = timeval_diff(&ts, &te);

	ok(nfds > 0, "fdset: poll returned %d events in %zu ms", nfds, diff);

	/* 5. Prepare event set. */
	ok(set.pfd[0].revents & POLLIN, "fdset: pipe is active");

	/* 6. Receive data. */
	char buf = 0x00;
	ret = read(set.pfd[0].fd, &buf, WRITE_PATTERN_LEN);
	ok(ret >= 0 && buf == WRITE_PATTERN, "fdset: contains valid data");

	/* 7-9. Remove from event set. */
	ret = fdset_remove(&set, 0);
	is_int(0, ret, "fdset: remove from fdset works");
	close(fds[0]);
	close(fds[1]);
	ret = fdset_remove(&set, 0);
	close(tmpfds[1]);
	close(tmpfds[1]);
	is_int(0, ret, "fdset: remove from fdset works (2)");
	ret = fdset_remove(&set, 0);
	ok(ret != 0, "fdset: removing nonexistent item");

	/* 10. Crash test. */
	fdset_init(0, 0);
	fdset_add(0, 1, 1, 0);
	fdset_add(0, 0, 1, 0);
	fdset_remove(0, 1);
	fdset_remove(0, 0);
	ok(1, "fdset: crash test successful");

	/* 11. Destroy fdset. */
	ret = fdset_clear(&set);
	is_int(0, ret, "fdset: destroyed");

	/* Cleanup. */
	pthread_join(t, 0);

	return 0;
}