Exemple #1
0
/**
 * Sends a cTCP segment to a destination associated with the provided
 * connection object.
 *
 * conn: Connection object.
 * segment: Pointer to cTCP segment to send.
 * len: Length of the segment (including the cTCP header and data).
 *
 * returns: The number of bytes actually sent, 0 if nothing was sent, -1 if
 *          there in an error.
 */
int conn_send(conn_t *conn, ctcp_segment_t *segment, size_t len) { ASSERT_CONN;
  /* Check parameters. */
  if (conn == NULL || segment == NULL) {
    fprintf(stderr, "[ERROR] NULL parameters in conn_send\n");
    return -1;
  }

  /* Make a copy of the segment first. */
  ctcp_segment_t *segment_copy = calloc(len, 1);
  memcpy(segment_copy, segment, len);

  /* Fork process off in order to do unreliability. Keep track of whether we
     are forked or not. */
  int fork_level = 0;
  bool am_i_forked = 0;

  /* Segment drop. Don't send the segment. */
  if ((test_debug_on && !tester_did_unreliable && opt_drop) ||
      (!test_debug_on && rand_percent(fork_level) < opt_drop)) {
    tester_did_unreliable = true;

    if (DEBUG) {
      fprintf(stderr, "[DEBUG] Dropping segment\n");
      print_hdr_ctcp(segment_copy);
    }
    free(segment_copy);
    return len;
  }

  /* Segment duplication. Fork another process to send the other segment. */
  if ((test_debug_on && !tester_did_unreliable && opt_duplicate) ||
      (!test_debug_on && rand_percent(fork_level) < opt_duplicate)) {
    tester_did_unreliable = true;

    if (DEBUG) {
      fprintf(stderr, "[DEBUG] Duplicating segment\n");
      print_hdr_ctcp(segment_copy);
    }
    if (fork() == 0) {
      am_i_forked = 1;
      fork_level++;
    }
  }

  /* Segment delay. Fork another process to delay the segment, and kill the
     current one. */
  if ((test_debug_on && !tester_did_unreliable && opt_delay) ||
       (!test_debug_on && rand_percent(fork_level) < opt_delay)) {
    tester_did_unreliable = true;

    if (DEBUG) {
      fprintf(stderr, "[DEBUG] Delaying segment\n");
      print_hdr_ctcp(segment_copy);
    }
    /* Forked process. Sleep for a bit. */
    if (fork() == 0) {
      am_i_forked = 1;
      fork_level++;
      sleep(rand() % 5);
    }
    /* Original process. */
    else {
      free(segment_copy);
      return len;
    }
  }

  /* Segment corruption. Flip bits in the segment after the TCP flags (to avoid
     corrupting the flags, which may cause problems). */
  bool do_corrupt = rand_percent(fork_level) < opt_corrupt;
  uint16_t data_length = len - sizeof(ctcp_segment_t) + sizeof(uint32_t);
  uint16_t rand_bit = rand() % (data_length * 8 - 1) +
                      (sizeof(ctcp_segment_t) - sizeof(uint32_t)) * 8;

  if ((test_debug_on && !tester_did_unreliable && opt_corrupt) ||
      (!test_debug_on && do_corrupt)) {
    tester_did_unreliable = true;

    if (DEBUG) {
      fprintf(stderr, "[DEBUG] Corrupting segment\n");
      print_hdr_ctcp(segment_copy);
    }
    flipbit(segment_copy, rand_bit);
  }

  uint16_t data_len = len - sizeof(ctcp_segment_t);
  uint16_t total_len = FULL_HDR_SIZE + data_len;

  if (log_file != -1 || test_debug_on) {
    log_segment(log_file, config->ip_addr, config->port, conn, segment_copy,
                len, true, unix_socket);
  }

  /* Convert from a cTCP segment to a real one and finally send the segment. */
  char *pkt = convert_to_datagram(conn, segment_copy, len);
  int n = send_pkt(conn, config->socket, pkt, total_len, 0);
  if (DEBUG) {
    fprintf(stderr, "[DEBUG] Sent segment\n");
    print_hdr_ctcp(segment_copy);
  }
  free(pkt);
  free(segment_copy);

  /* Kill forked process. */
  if (am_i_forked)
    exit(0);

  /* Return number of bytes sent. Need to subtract some because the return value
     is actually the size of the TCP segment instead of the cTCP segment. */
  if (n >= (long int)TCP_HDR_SIZE)
    return n - (TCP_HDR_SIZE + IP_HDR_SIZE - sizeof(ctcp_segment_t));
  return n;
}
int main(){
	int mv = setbit (5,1);
	int nnv = flipbit(mv, 2);
	printf("%x..%x\n", mv, nnv);
	return 0;
}