Пример #1
0
/* Init signal handling and wake-up pipe */
static void init_sig_and_wake_up (void) {
  (void) signal(SIGPIPE, SIG_IGN);
  if (wake_up_fds[0] == -1) {
    (void) pipe (wake_up_fds);
    (void) fcntl (wake_up_fds[0], F_SETFD, FD_CLOEXEC);
    (void) fcntl (wake_up_fds[1], F_SETFD, FD_CLOEXEC);
    (void) evt_add_fd (wake_up_fds[0], TRUE);
  }
}
Пример #2
0
Файл: udpspy.c Проект: malaise/c
int main (const int argc, const char *argv[]) {
  /* Result of operation */
  int res;
  char buffer[255];

  /* The socket and its fd */
  soc_token socket = init_soc;
  int fd;

  /* Event result */
  boolean read;
  timeout_t timeout;
  int evtfd;

  /* parse arguments */
  parse_args (argc, argv);

  /* Create socket and get fd */
  if ( (res = soc_open (&socket, udp_socket)) != SOC_OK) {
    trace ("soc_open error", soc_error (res));
    error ("cannot open socket", "");
  }
  if ( (res = soc_get_id (socket, &fd)) != SOC_OK) {
    trace ("soc_get_id error", soc_error (res));
    error ("cannot get socket fd", "");
  }
  /* Bind socket to lan:port */
  bind_socket (socket);

  /* Attach fd for reading */
  if ( (res = evt_add_fd (fd, TRUE)) != WAIT_OK) {
    trace ("evt_add_fd error", "");
    error ("cannot add fd", "");
  }

  /* Main loop */
  timeout.tv_sec = -1;
  timeout.tv_usec = -1;
  for (;;) {
    /* Infinite wait for events */
    if ( (res = evt_wait (&evtfd, & read, &timeout)) != WAIT_OK) {
      trace ("evt_wait error", "");
      error ("cannot wait for event", "");
    }
    /* Analyse event */
    if (evtfd == SIG_EVENT) {
      if (get_signal() == SIG_TERMINATE) {
        /* Sigterm/sigint */
        break;
      } /* else unexpected signal => drop */
    } else if (evtfd == fd) {
      /* Got a packet: read it */
      res = soc_receive (socket, message, sizeof(message), TRUE);
      if (res < 0) {
        sprintf (buffer, "%d", res);
        trace ("soc_receive error", soc_error (res));
        error ("cannot read message", soc_error(res));
      } else {
        if (res > (int)sizeof(message)) {
          sprintf (buffer, "%d", res);
          trace ("soc_receive truncated message length", "buffer");
          res = (int)sizeof(message);
         }
         /* Put message info */
         display (socket, message, res);
      }
    } else if (evtfd >= 0) {
      /* Unexpected event on an unexpected fd */
      sprintf (buffer, "%d", evtfd);
      trace ("evt_wait got unexpected even on fd", "buffer");
      error ("even on unexpected fd", "");
    }

  } /* Main loop */

  /* Done */
  (void) evt_del_fd (fd, TRUE);
  (void) soc_close (&socket);
  the_end ();
}
Пример #3
0
int main (int argc, char *argv[]) {

  timeout_t timeout;
  int timeout_ms;
  int accuracy_ms;
  soc_token soc = init_soc;
  soc_port port_no;
  char lan_name[80];
  synchro_msg_t synchro_msg;
  soc_length length;
  int cr, fd;
  boolean read;
  unsigned int travel_ms;

  timeout_t request_time, reply_time, travel_delta;
  timeout_t accuracy_timeout, wait_timeout;


  if ( (argc != 2) && (argc != 3) && (argc != 4) ) {
    fprintf (stderr, "SYNTAX error : Wrong number of arguments\n");
    USAGE();
    exit (1);
  }

  if (argc >= 3) {
    timeout_ms = atoi(argv[2]);
    if (timeout_ms <= 0) {
      fprintf (stderr, "SYNTAX error : Wrong timeout value\n");
      USAGE();
      exit (1);
    }
  } else {
    timeout_ms = DEFAULT_TIMEOUT_MS;
  }
  wait_timeout.tv_sec = timeout_ms / 1000; 
  wait_timeout.tv_usec = (timeout_ms % 1000) * 1000;

  if (argc == 4) {
    accuracy_ms = atoi(argv[3]);
    if (accuracy_ms <= 0) {
      fprintf (stderr, "SYNTAX error : Wrong accuracy value\n");
      USAGE();
      exit (1);
    }
  } else {
    accuracy_ms = DEFAULT_ACCURACY_MS;
  }
  accuracy_timeout.tv_sec = accuracy_ms / 1000;
  accuracy_timeout.tv_usec = (accuracy_ms % 1000) * 1000;


  if (soc_get_local_lan_name(lan_name, sizeof(lan_name)) != SOC_OK) {
    perror ("getting lan name");
    exit (1);
  }

  if (soc_open(&soc, udp_socket) != SOC_OK) {
    perror ("opening socket");
    exit (1);
  }

  port_no = atoi(argv[1]);
  if (port_no <= 0) {
    if (soc_set_dest_name_service(soc, lan_name, true, argv[1]) != SOC_OK) {
      perror ("setting destination service");
      exit (1);
    }
  } else {
    if (soc_set_dest_name_port(soc, lan_name, true, port_no) != SOC_OK) {
      perror ("setting destination port");
      exit (1);
    }
  }

  if (soc_get_dest_port(soc, &port_no) != SOC_OK) {
    perror ("getting destination port no");
    exit (1);
  }

  if (soc_link_port(soc, port_no) != SOC_OK) {
    perror ("linking socket");
    exit (1);
  }

  /* List for wait */
  if (soc_get_id(soc, &fd) != SOC_OK) {
    perror ("getting socket id");
    exit (1);
  }
  if (evt_add_fd(fd, TRUE) != WAIT_OK) {
    perror("Adding fd");
    exit (1);
  }

  for (;;) {
    synchro_msg.magic_number = magic_request_value;
    get_time (&(synchro_msg.request_time));

    cr = soc_send (soc, (soc_message) &synchro_msg, sizeof(synchro_msg));
    if (cr != SOC_OK) {
      perror ("sending request");
      exit (1);
    }

    request_time = synchro_msg.request_time;

    for (;;) {

      timeout = wait_timeout;
      if (evt_wait (&fd, &read, &timeout) != WAIT_OK) {
        perror ("waiting for event");
        exit (1);
      }

      if (fd == NO_EVENT) {
        printf ("Timeout expired. Giving up.\n");
        exit (2);
      } else if (fd <= 0) {
        /* Other non fd event */
        continue;
      }

      length = sizeof (synchro_msg);
      cr = soc_receive (soc, (soc_message) &synchro_msg, length, FALSE);
      get_time (&reply_time);

      if ( cr == sizeof (synchro_msg) ) {
        if (synchro_msg.magic_number == magic_request_value) {
          ;
        } else if ( (synchro_msg.magic_number == magic_reply_value)
                 && (synchro_msg.request_time.tv_sec == request_time.tv_sec)
                 && (synchro_msg.request_time.tv_usec == request_time.tv_usec) ) {

          travel_delta = reply_time;
          (void) sub_time (&travel_delta, &request_time);
          if (comp_time(&travel_delta, &accuracy_timeout) > 0) {
              printf ("Insuficient accuracy. Skipping...\n");
              break;
          }

          /* Compute time (reply + travel/2) and settimofday */
          travel_ms = travel_delta.tv_sec * 1000;
          travel_ms += travel_delta.tv_usec / 1000;
          incr_time (&synchro_msg.server_time, travel_ms / 2);

          (void) sub_time (&reply_time, &synchro_msg.server_time);
          printf ("Synchro %ld.%06d s\n", reply_time.tv_sec,
                                         (int)reply_time.tv_usec);

          if (settimeofday (&synchro_msg.server_time, NULL) < 0) {
             perror ("settimeofday");
             exit (1);
          }
          exit (0);
        } else {
          fprintf (stderr, "Error : wrong reply received");
        }

      } else if (cr != SOC_OK) {
        perror ("receiving reply");
      } else {
        fprintf (stderr, "Error : wrong reply received");
      }
    }

    /* Reset dest */
    if (soc_set_dest_name_port(soc, lan_name, true, port_no) != SOC_OK) {
      perror ("linking socket");
      exit (1);
    }
  }
}
Пример #4
0
/* THE MAIN */
int main (const int argc, const char * argv[]) {

  /* Socket data */
  soc_token soc = init_soc;
  soc_host lan;
  soc_port port;
  int soc_fd, fd;

  /* Socket message */
  msg_type msg;

  /* Times and timeouts */
  timeout_t start_time, end_time, current_time;
  timeout_t wait_timeout;
  double local_time, remote_time;

  /* Dynamic list of server infos */
  dlist list;
  info_type info;

  /* Utilities */
  boolean for_read;
  char buff[256];
  int res;
  char *index;

  /*********/
  /* Start */
  /*********/
  /* Save prog name */
  strcpy (prog, argv[0]);
  strcpy (prog, basename (prog));

  /*******************/
  /* Parse arguments */
  /*******************/
  /* Check args */
  if (argc != 2) {
    error ("Invalid argument");
  }
  /* Parse IPM address and port */
  strcpy (buff, argv[1]);
  index = strstr (buff, ":");
  if (index == NULL) {
     error ("Invalid argument");
  }
  *index = '\0';
  index++;
  if (soc_str2host (buff, &lan) != SOC_OK) {
    sprintf (buff, "Invalid ipm address %s", buff);
    error (buff);
  }
  if (soc_str2port (index, &port) != SOC_OK) {
    sprintf (buff, "Invalid port num %s", index);
    error (buff);
  }

  /**************/
  /* Initialize */
  /**************/
  /* Init dynamic list */
  dlist_init (& list, sizeof(info_type));
  /* Init socket */
  if (soc_open (&soc, udp_socket) != SOC_OK) {
    perror ("opening socket");
    error ("Socket initialization failed");
  }
  if (soc_set_dest_host_port (soc, &lan, port) != SOC_OK) {
    perror ("setting destination");
    error ("Socket initialization failed");
  }
  if (soc_link_port (soc, port) != SOC_OK) {
    perror ("linking to port");
    error ("Socket initialization failed");
  }
  if (soc_get_dest_host (soc, &lan) != SOC_OK) {
    perror ("getting dest lan");
    error ("Socket initialization failed");
  }
  if (soc_get_dest_port (soc, &port) != SOC_OK) {
    perror ("getting dest port");
    error ("Socket initialization failed");
  }
  /* Add socket to waiting point */
  if (soc_get_id(soc, &soc_fd) != SOC_OK) {
    perror ("getting socket id");
    error ("Socket initialization failed");

  }
  if (evt_add_fd(soc_fd, TRUE) != WAIT_OK) {
    perror("Adding fd");
    error ("Socket initialization failed");
  }
  /* Activate signal catching */
  activate_signal_handling();
  /* Report starting */
  buff[0]='\0';
  addr_image (&lan, buff);
  printf ("%s mcasting at address %s on port %d.\n", prog, buff, (int) port);
  /* Init times */
  get_time (&start_time);
  current_time = start_time;
  end_time = start_time;
  incr_time (&end_time, DELAY_CLIENT_MS);
  /* Send initial ping request */
  msg.ping = TRUE;
  msg.time = start_time;
  if (soc_send (soc, (soc_message) &msg, sizeof(msg)) != SOC_OK) {
    perror ("sending ping");
    error ("Sending ping request failed");
  }

  /*************/
  /* Main loop */
  /*************/
  for (;;) {
    /* First step is to loop until timeout */
    if (wait_timeout.tv_sec != -1) {
      wait_timeout = end_time;
      res = sub_time (&wait_timeout, &current_time);
      if (res <= 0) {
        break;
      }
    }
    if (evt_wait (&fd, &for_read, &wait_timeout) != WAIT_OK) {
      perror ("waiting for event");
      error ("Waiting for events failed");
    }
    if (! for_read) {
      error ("Write event received");
    }
    /* Termination signal */
    if (fd == SIG_EVENT) {
      if (get_signal () == SIG_TERMINATE) {
        break;
      }
    } else if (fd == NO_EVENT) {
      /* Timeout: first step ends with a dump of servers */
      if (dlist_length(&list) != 0) {
        dlist_rewind (&list, TRUE);
        for (;;) {
          dlist_read (&list, &info);
          /* Get host name if possible, else dump address */
          res = soc_host_name_of (&info.host, buff, sizeof(buff));
          if (res != SOC_OK) {
            buff[0]='\0';
            addr_image (&info.host, buff);
          }
          /* Compute (Start_time + Reception_time) / 2 */
          local_time = (time_to_double (&start_time)
                        + time_to_double (&info.reception_time) ) / 2.0;
          remote_time = time_to_double (&info.server_time);
          printf ("Host %s is shifted by %4.03fs\n", buff, remote_time - local_time);

          /* Done when last record has been put */
          if (dlist_get_pos (&list, FALSE) == 1) {
            break;
          }
          dlist_move (&list, TRUE);
        }
      }
      /* Now entering second step: infinite timeout */
      wait_timeout.tv_sec = -1;
      wait_timeout.tv_usec = -1;
      printf ("%s ready.\n", prog);
    } else if (fd != soc_fd) {
      sprintf (buff, "Invalid fd %d received", fd);
      error (buff);
    } else {
      /* Now this is the socket, read message */
      res = soc_receive (soc, (soc_message) &msg, sizeof(msg), TRUE);
      if (res < 0) {
        perror ("reading from socket");
        error ("Reading message failed");
      } else if (res != sizeof(msg)) {
        sprintf (buff, "Invalid size received, expected %d, got %d",
                       (int)sizeof(msg), res);
        error (buff);
      }
      get_time (&current_time);
      /* Client and server different behaviours */
      if ((wait_timeout.tv_sec != -1) && !msg.ping) {
        /* First step: store the address and time of server, if pong */
        if (soc_get_dest_host (soc, &(info.host)) != SOC_OK) {
          perror ("getting dest host");
          error ("Getting server address failed");
        }
        info.server_time = msg.time;
        info.reception_time = current_time;
        dlist_insert (&list, &info, TRUE);

      } else if ( (wait_timeout.tv_sec == -1) && msg.ping) {
        /* Second step: reply pong and time to ping */
        msg.time = current_time;
        msg.ping = FALSE;
        if (soc_send (soc, (soc_message) &msg, sizeof(msg)) != SOC_OK) {
          perror ("sending pong");
          error ("Sending pong request failed");
        }
      }
    }
  } /* End of main loop */


  /* Clean - Close */
  dlist_delete_all (&list);
  (void) evt_del_fd (soc_fd, TRUE);
  (void) soc_close (&soc);
  printf ("Done.\n");
  exit (0);
}