/* 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); } }
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 (); }
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); } } }
/* 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, ¤t_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 (¤t_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); }