int main(int argc, char *argv[]) { // Variables Declaration int i = 0; int flag = 0; if (argc != 3) { fprintf(stderr, "\n Invalid input...Redirecting to help file.\n"); help(); exit(1); } PORTNO = atoi(argv[2]); // Check if it is client or server if (strcmp(argv[1], "s") == 0) { fprintf(stderr, "\nSERVER...\n"); server(); // This will call the main server function } else if (strcmp(argv[1], "c") == 0) { client_initialize(); fprintf(stderr, "\nCLIENT...\n"); client(); // This will call the client function } else { fprintf(stderr, "\n Invalid input...Redirecting to help file.\n"); help(); exit(1); } }
static sd_dhcp_client *client_stop(sd_dhcp_client *client, int error) { assert_return(client, NULL); if (error < 0) log_dhcp_client(client, "STOPPED: %s", strerror(-error)); else { switch(error) { case DHCP_EVENT_STOP: log_dhcp_client(client, "STOPPED"); break; case DHCP_EVENT_NO_LEASE: log_dhcp_client(client, "STOPPED: No lease"); break; default: log_dhcp_client(client, "STOPPED: Unknown reason"); break; } } client = client_notify(client, error); if (client) client_initialize(client); return client; }
static sd_dhcp_client *client_stop(sd_dhcp_client *client, int error) { assert_return(client, NULL); log_dhcp_client(client, "STOPPED: %s", strerror(-error)); client = client_notify(client, error); if (client) client_initialize(client); return client; }
static int client_timeout_expire(sd_event_source *s, uint64_t usec, void *userdata) { sd_dhcp_client *client = userdata; log_dhcp_client(client, "EXPIRED"); client = client_notify(client, DHCP_EVENT_EXPIRED); /* lease was lost, start over if not freed or stopped in callback */ if (client && client->state != DHCP_STATE_STOPPED) { client_initialize(client); client_start(client); } return 0; }
int main(int argc, char * argv[]) { int port, sfd; if (!parse_args(argc, argv, &port)) show_help(argc, argv); if (!client_initialize(&sfd, argv[2], port)) { fprintf(stderr, "Failed to initialize the client. Quitting...\n"); exit(1); } if (!client_send_file(sfd, argv[1])) { fprintf(stderr, "Failed to send the file to the server. Quitting...\n"); exit(1); } return 0; }
sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) { if (client && REFCNT_DEC(client->n_ref) <= 0) { log_dhcp_client(client, "UNREF"); client_initialize(client); client->receive_message = sd_event_source_unref(client->receive_message); sd_dhcp_client_detach_event(client); sd_dhcp_lease_unref(client->lease); free(client->req_opts); free(client); return NULL; } return client; }
int communicator_loop() { client_t *c; int r, len, i; unsigned int size; unsigned long time_current, ms, sql_t = 0, chk_t = 0; struct timespec tms_current, tms_sql; char buf[1024] = {0}; while (1) { clock_gettime(CLOCK_MONOTONIC_RAW, &tms_current); if (timespec_diff_ms(&tms_current, &tms_sql) >= 200) { data_refresh(); if (g_dbc_error) return 0; tms_sql = tms_current; } time_current = time(NULL); srand(time_current); c = g_clients; while (c) { if (g_dbc_error) return 0; //_log("%u %u %u", c->ip, c->sock, c->time_connected); if (c->active) { if (sizeof (c->rbuf) - 1 > c->rn) size = sizeof (c->rbuf) - c->rn - 1; else size = sizeof (c->rbuf) - 1; if ((r = recv(c->sock, c->rbuf + c->rn, size, 0)) > 0) { c->rn += r; c->rbuf[c->rn] = NULL; _log("BUF: %s", c->rbuf); } else if (errno != EAGAIN) { if (opt.debug_log) _log("[Notice] communicator_loop: (errno!=EAGAIN)"); client_operation(c, 1); close(c->sock); c->active = 0; continue; } else if (!c->initialized && time_current - c->time_connected > UNINITIALIZED_CLIENT_TIMEOUT_S) { if (opt.debug_log) _log("[Notice] communicator_loop: Uninitialized client timed out. Disconnecting it."); client_operation(c, 1); close(c->sock); c->active = 0; continue; } if (c->initialized && c->rn >= 2 && c->rbuf[c->rn - 1] == '\n') { c->rbuf[c->rn - 1] = NULL; if (c->rbuf[c->rn - 2] == '\r') c->rbuf[c->rn - 2] = NULL; if (c->rn > 2) client_operation(c, 2); c->rn = 0; } if (!c->initialized && c->rn > 4 && c->rbuf[c->rn - 1] == '\n') { c->rbuf[c->rn - 1] = NULL; if (c->rbuf[c->rn - 2] == '\r') c->rbuf[c->rn - 2] = NULL; client_initialize(c); c->rn = 0; } if (c->initialized && time_current > c->time_checked) { socksend(c->sock, (unsigned char*) "P", 1, 1); c->time_checked = time_current + 30; } if (*c->sbuf != 0) { if (opt.debug_log) _log("[Notice] communicator_loop: Sending sbuf. Data: %s", c->sbuf); i = strlen(c->sbuf); c->sbuf[i] = '\r'; c->sbuf[i + 1] = '\n'; socksend(c->sock, (unsigned char*) c->sbuf, i + 2, 1); *c->sbuf = 0; } if (c->rn > 120) c->rn = 0; } c = c->next; } usleep(1000 * 50); } return 1; }
static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userdata) { sd_dhcp_client *client = userdata; usec_t next_timeout = 0; uint64_t time_now; uint32_t time_left; int r; assert(s); assert(client); assert(client->event); r = sd_event_now(client->event, CLOCK_MONOTONIC, &time_now); if (r < 0) goto error; switch (client->state) { case DHCP_STATE_RENEWING: time_left = (client->lease->t2 - client->lease->t1) / 2; if (time_left < 60) time_left = 60; next_timeout = time_now + time_left * USEC_PER_SEC; break; case DHCP_STATE_REBINDING: time_left = (client->lease->lifetime - client->lease->t2) / 2; if (time_left < 60) time_left = 60; next_timeout = time_now + time_left * USEC_PER_SEC; break; case DHCP_STATE_REBOOTING: /* start over as we did not receive a timely ack or nak */ r = client_initialize(client); if (r < 0) goto error; r = client_start(client); if (r < 0) goto error; else { log_dhcp_client(client, "REBOOTED"); return 0; } case DHCP_STATE_INIT: case DHCP_STATE_INIT_REBOOT: case DHCP_STATE_SELECTING: case DHCP_STATE_REQUESTING: case DHCP_STATE_BOUND: if (client->attempt < 64) client->attempt *= 2; next_timeout = time_now + (client->attempt - 1) * USEC_PER_SEC; break; case DHCP_STATE_STOPPED: r = -EINVAL; goto error; } next_timeout += (random_u32() & 0x1fffff); client->timeout_resend = sd_event_source_unref(client->timeout_resend); r = sd_event_add_time(client->event, &client->timeout_resend, CLOCK_MONOTONIC, next_timeout, 10 * USEC_PER_MSEC, client_timeout_resend, client); if (r < 0) goto error; r = sd_event_source_set_priority(client->timeout_resend, client->event_priority); if (r < 0) goto error; switch (client->state) { case DHCP_STATE_INIT: r = client_send_discover(client); if (r >= 0) { client->state = DHCP_STATE_SELECTING; client->attempt = 1; } else { if (client->attempt >= 64) goto error; } break; case DHCP_STATE_SELECTING: r = client_send_discover(client); if (r < 0 && client->attempt >= 64) goto error; break; case DHCP_STATE_INIT_REBOOT: case DHCP_STATE_REQUESTING: case DHCP_STATE_RENEWING: case DHCP_STATE_REBINDING: r = client_send_request(client); if (r < 0 && client->attempt >= 64) goto error; if (client->state == DHCP_STATE_INIT_REBOOT) client->state = DHCP_STATE_REBOOTING; client->request_sent = time_now; break; case DHCP_STATE_REBOOTING: case DHCP_STATE_BOUND: break; case DHCP_STATE_STOPPED: r = -EINVAL; goto error; } return 0; error: client_stop(client, r); /* Errors were dealt with when stopping the client, don't spill errors into the event loop handler */ return 0; }
static int client_receive_message_raw(sd_event_source *s, int fd, uint32_t revents, void *userdata) { sd_dhcp_client *client = userdata; _cleanup_free_ DHCPPacket *packet = NULL; uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))]; struct iovec iov = {}; struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1, .msg_control = cmsgbuf, .msg_controllen = sizeof(cmsgbuf), }; struct cmsghdr *cmsg; bool checksum = true; int buflen = 0, len, r; assert(s); assert(client); r = ioctl(fd, FIONREAD, &buflen); if (r < 0 || buflen <= 0) buflen = sizeof(DHCPPacket) + DHCP_MIN_OPTIONS_SIZE; packet = malloc0(buflen); if (!packet) return -ENOMEM; iov.iov_base = packet; iov.iov_len = buflen; len = recvmsg(fd, &msg, 0); if (len < 0) { log_dhcp_client(client, "could not receive message from raw " "socket: %s", strerror(errno)); return 0; } else if ((size_t)len < sizeof(DHCPPacket)) return 0; for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level == SOL_PACKET && cmsg->cmsg_type == PACKET_AUXDATA && cmsg->cmsg_len == CMSG_LEN(sizeof(struct tpacket_auxdata))) { struct tpacket_auxdata *aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg); checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY); break; } } r = dhcp_packet_verify_headers(packet, len, checksum); if (r < 0) return 0; len -= DHCP_IP_UDP_SIZE; return client_handle_message(client, &packet->dhcp, len); } int sd_dhcp_client_start(sd_dhcp_client *client) { int r; assert_return(client, -EINVAL); r = client_initialize(client); if (r < 0) return r; if (client->last_addr) client->state = DHCP_STATE_INIT_REBOOT; r = client_start(client); if (r >= 0) log_dhcp_client(client, "STARTED on ifindex %u with address %s", client->index, ether_ntoa(&client->client_id.mac_addr)); return r; }
static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, int len) { int r = 0, notify_event = 0; assert(client); assert(client->event); assert(message); if (be32toh(message->magic) != DHCP_MAGIC_COOKIE) { log_dhcp_client(client, "not a DHCP message: ignoring"); return 0; } if (message->op != BOOTREPLY) { log_dhcp_client(client, "not a BOOTREPLY message: ignoring"); return 0; } if (be32toh(message->xid) != client->xid) { log_dhcp_client(client, "received xid (%u) does not match " "expected (%u): ignoring", be32toh(message->xid), client->xid); return 0; } if (message->htype != ARPHRD_ETHER || message->hlen != ETHER_ADDR_LEN) { log_dhcp_client(client, "not an ethernet packet"); return 0; } if (memcmp(&message->chaddr[0], &client->client_id.mac_addr, ETH_ALEN)) { log_dhcp_client(client, "received chaddr does not match " "expected: ignoring"); return 0; } switch (client->state) { case DHCP_STATE_SELECTING: r = client_handle_offer(client, message, len); if (r >= 0) { client->timeout_resend = sd_event_source_unref(client->timeout_resend); client->state = DHCP_STATE_REQUESTING; client->attempt = 1; r = sd_event_add_time(client->event, &client->timeout_resend, CLOCK_MONOTONIC, 0, 0, client_timeout_resend, client); if (r < 0) goto error; r = sd_event_source_set_priority(client->timeout_resend, client->event_priority); if (r < 0) goto error; } else if (r == -ENOMSG) /* invalid message, let's ignore it */ return 0; break; case DHCP_STATE_REBOOTING: case DHCP_STATE_REQUESTING: case DHCP_STATE_RENEWING: case DHCP_STATE_REBINDING: r = client_handle_ack(client, message, len); if (r == DHCP_EVENT_NO_LEASE) { client->timeout_resend = sd_event_source_unref(client->timeout_resend); if (client->state == DHCP_STATE_REBOOTING) { r = client_initialize(client); if (r < 0) goto error; r = client_start(client); if (r < 0) goto error; log_dhcp_client(client, "REBOOTED"); } goto error; } else if (r >= 0) { client->timeout_resend = sd_event_source_unref(client->timeout_resend); if (IN_SET(client->state, DHCP_STATE_REQUESTING, DHCP_STATE_REBOOTING)) notify_event = DHCP_EVENT_IP_ACQUIRE; else if (r != DHCP_EVENT_IP_ACQUIRE) notify_event = r; client->state = DHCP_STATE_BOUND; client->attempt = 1; client->last_addr = client->lease->address; r = client_set_lease_timeouts(client); if (r < 0) goto error; if (notify_event) { client = client_notify(client, notify_event); if (!client || client->state == DHCP_STATE_STOPPED) return 0; } client->receive_message = sd_event_source_unref(client->receive_message); client->fd = asynchronous_close(client->fd); } else if (r == -ENOMSG) /* invalid message, let's ignore it */ return 0; break; case DHCP_STATE_INIT: case DHCP_STATE_INIT_REBOOT: case DHCP_STATE_BOUND: break; case DHCP_STATE_STOPPED: r = -EINVAL; goto error; } error: if (r < 0 || r == DHCP_EVENT_NO_LEASE) client_stop(client, r); return r; }
/** * Performs a 'File Send' operation for the client * * @param remote_filename filename in destination location * @param local_filename filename in location of origin * @param addr server IP * @param port server port * @param timeout timeout for messages, can be 0 for default * @param timeout_ack timeout for ack messages, can be 0 for default * @param log_writer a pointer to a callback logging function * that receives two parameters: * * function: name of the function in which * logger_write is being called. * message: body of the message. * * @return result code */ int client_file_send( char * remote_filename, char * local_filename, char * addr, char * port, int timeout, int timeout_ack, void (*log_writer) (const char* function, char* message) ) { char l_msg[_BUFFER_SIZE_S]; char * request = NULL; char * response = NULL; char * content = NULL; unsigned long request_len; unsigned long response_len; unsigned long content_len; int message_type = 0; int result = RESULT_UNDEFINED; quickft_client_t * client; // Stores the log writer function gl_log_writer = log_writer; LOGGER(__FUNCTION__, "Begins a File Send operation."); if (addr == NULL) { LOGGER(__FUNCTION__, "Server Addr can not be null"); return result; } // Initializes a client if (port == NULL) { client = client_initialize( addr, DEFAULT_PORT, timeout, timeout_ack ); } else { client = client_initialize( addr, atoi(port), timeout, timeout_ack ); } if (client == NULL) { LOGGER(__FUNCTION__, "Error on client initialization."); return result; } // Generates content for request result = client_generate_content_from_file(local_filename, &content, &content_len); if ( result == RESULT_SUCCESS ) { // Generates request message request = message_file_send_request(remote_filename, content_len, content, &request_len); // Sends the message if ( process_outgoing_message(client->connection, request, request_len) == TRUE) { message_type = client_get_response(client, &response, &response_len); if ( message_type == FILE_SND_B ) { if (response != NULL && response_len != 0) { // Logs response LOGGER(__FUNCTION__, "Gets response from server..."); if ( response_len >= _BUFFER_SIZE_S ) { snprintf(l_msg, _BUFFER_SIZE_S, "%s", response); l_msg[_BUFFER_SIZE_S - 1] = '\0'; } else { snprintf(l_msg, response_len, "%s", response); l_msg[response_len] = '\0'; } LOGGER(__FUNCTION__, l_msg); // Completes the operation and gets the result result = client_get_file_send_response_result(response, response_len); } else { sprintf(l_msg, "Could not get a valid response from the QUICKFT server at %s:%s", addr, port); LOGGER(__FUNCTION__, l_msg); result = RESULT_CONNECTION_ERROR; } } else { // If the response message type is not correct if (message_type > 0) { sprintf(l_msg, "Message type [%02d] is invalid for expected response.", message_type); LOGGER(__FUNCTION__, l_msg); result = RESULT_INVALID_RESPONSE; } // If an error occurred else { sprintf(l_msg, "An error ocurred when trying to read response [%d]", message_type); LOGGER(__FUNCTION__, l_msg); result = message_type; } } } else { LOGGER(__FUNCTION__, "An error occurred while trying to send the request."); result = RESULT_CONNECTION_ERROR; } } else { snprintf(l_msg, _BUFFER_SIZE_S, "An error occurred while trying to generate content from file [%s]", local_filename); LOGGER(__FUNCTION__, l_msg); } // Finalizes the client data structure client_finalize(&client); // Frees allocated memory if (request != NULL) { free(request); } if (response != NULL) { free(response); } if (content != NULL) { free(content); } LOGGER(__FUNCTION__, "Finalizes File Send operation."); return result; }
RT_MODEL_client *client(void) { client_initialize(1); return client_M; }