From bc3f496788662f820e86fcaa10477d121bec93ac Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Sun, 14 Sep 2014 09:50:08 -0500 Subject: [PATCH] Ntk-console: Stop using fixed buffer width. * Detect end of string in console and act on that. * Open console connection on startup * Terminate console connection on exit --- src/Ntk-Console/Netsukuku-Console.c | 170 +++++++--------- src/Ntk-Console/Netsukuku-Console.h | 41 +++- src/ntk-console-bindings.c | 295 +++++++++++++--------------- 3 files changed, 247 insertions(+), 259 deletions(-) diff --git a/src/Ntk-Console/Netsukuku-Console.c b/src/Ntk-Console/Netsukuku-Console.c index bff1aa3..c7e6d70 100644 --- a/src/Ntk-Console/Netsukuku-Console.c +++ b/src/Ntk-Console/Netsukuku-Console.c @@ -1,29 +1,11 @@ + #include "Netsukuku-Console.h" +#include + + char response[BUFFER_LENGTH]; -void usage(); - -void clean_up(); - - -typedef enum { - COMMAND_HELP = 0x100, - COMMAND_UPTIME, - COMMAND_KILL, - COMMAND_VERSION, - COMMAND_INETCONN, - COMMAND_CURIFS, - COMMAND_CURIFSCT, - COMMAND_CURQSPNID, - COMMAND_CURIP, - COMMAND_CURNODE, - COMMAND_IFS, - COMMAND_IFSCT, - COMMAND_QUIT, - COMMAND_CONSUPTIME, -} command_t; - const struct supported_commands { command_t id; @@ -69,21 +51,28 @@ command_parse(char *request) } -void -response_cleanup(char response[BUFFER_LENGTH]) +static int +request_receive(int sock, char message[], int max) { - char remove = 'a'; - - char* c; - char* pPosition; - while((pPosition = strchr(response, 'a')) != NULL) { - if ((c = index(response, remove)) != NULL) { - size_t len_left = sizeof(response) - (c+1-response); - memmove(c, c+1, len_left); - } + int total = 0; + const int bsize = 1024; + char buffer[bsize+1]; + int read = bsize; + + message[0] = 0; // initialize for strcat() + + while(read == bsize) { + read = recv(sock, buffer, bsize, 0); + if(read < 0) + return -1; // error, bail out + total += read; + if(total > max) + return -2; // overflow + buffer[read] = 0; + strcat(message, buffer); } - printf("Sent and received Successfully!\n The Response was: %s", response); + return total; } @@ -91,37 +80,28 @@ response_cleanup(char response[BUFFER_LENGTH]) void ntkd_request(char *request) { - rc = connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)); - if (rc < 0) { - perror("connect() failed"); + if (sockfd <= 0) { + perror("ntkd connection closed unexpectedly!\n"); exit(-1); } - int request_length = strlen(request); - memset(request, 'a', BUFFER_LENGTH - request_length); - rc = send(sockfd, request, sizeof(request), 0); + int request_length = strlen(request) - 1; + request[request_length] = '\0'; + + printf("request: '%s'\n", request); + rc = send(sockfd, request, request_length, 0); if (rc < 0) { perror("send() failed"); exit(-1); } - bytesReceived = 0; - while (bytesReceived < BUFFER_LENGTH) { - rc = recv(sockfd, & response[bytesReceived], - BUFFER_LENGTH - bytesReceived, 0); - if (rc < 0) { - perror("recv() failed"); - exit(-1); - } - else if (rc == 0) { - printf("The server closed the connection\n"); + request_receive(sockfd, response, BUFFER_LENGTH); + if (rc < 0) { + perror("recv() failed"); exit(-1); } - /* Increment the number of bytes that have been received so far */ - bytesReceived += rc; - } - response_cleanup(response); + printf("%s\n", response); } @@ -137,6 +117,28 @@ opensocket(void) memset(&serveraddr, 0, sizeof(serveraddr)); serveraddr.sun_family = AF_UNIX; strcpy(serveraddr.sun_path, SERVER_PATH); + + rc = connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)); + if (rc < 0) { + perror("connect() failed"); + exit(-1); + } + printf("ntkd console connection opened successfully.\n"); +} + + +void +closesocket(void) +{ + const int optVal = 1; + const socklen_t optLen = sizeof(optVal); + + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*) &optVal, optLen); + + if (sockfd >= 0) + close(sockfd); + + printf("ntkd console connection closed.\n"); } @@ -175,10 +177,10 @@ console_uptime(void) } -int +static void millisleep(unsigned ms) { - return usleep(1000 * ms); + usleep(1000 * ms); } @@ -189,7 +191,7 @@ console(char* request) switch (commandID) { case COMMAND_QUIT: - clean_up(); + closesocket(); exit(0); case COMMAND_UPTIME: case COMMAND_INETCONN: @@ -211,6 +213,7 @@ console(char* request) console_uptime(); break; case COMMAND_KILL: + closesocket(); system("ntkd -k"); break; case COMMAND_HELP: @@ -234,61 +237,28 @@ main(void) uptime_month = timeinfo->tm_mon; uptime_year = timeinfo->tm_year; - opensocket(); - printf("This is the Netsukuku Console, Please type 'help' for more information.\n"); char* request = (char*)malloc(BUFFER_LENGTH); + opensocket(); do { - printf("\n>"); + printf("\n> "); fgets(request, 16, stdin); fflush(stdin); console(request); - } while(FALSE); + memset(request, 0, BUFFER_LENGTH); + } while(TRUE); + closesocket(); clean_up(); return 0; } void usage(void) { - - printf("Usage\n" - " uptime Returns the time when ntkd finished the hooking,\n" - " to get the the actual uptime just do)\n" - " time(0)-me.uptime \n" - " help Shows this\n" - " kill Kills the running instance of netsukuku with SIGINT\n\n" - " version Shows the running version of the ntk-console, and ntkd.\n" - " inet_connected If it is 1, Ntkd is connected to the Internet\n" - " \n" - " cur_ifs Lists all of the interfaces in cur_ifs\n" - " cur_ifs_n Lists the number of interfaces present in `cur_ifs'\n" - " cur_qspn_id The current qspn_id we are processing. " - " It is cur_qspn_id[levels] big\n" - " cur_ip Current IP address\n" - " \n" - " cur_node Current Node\n" - " ifs Lists all of the interfaces in server_opt.ifs\n" - " ifs_n Lists the number of interfaces present in server_opt.ifs\n" - " quit Exits this program\n" - " console_uptime Gets the uptime of this console\n"); - -} - -void clean_up(void) -{ - const int optVal = 1; - const socklen_t optLen = sizeof(optVal); - - setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*) &optVal, optLen); - setsockopt(sockfd1, SOL_SOCKET, SO_REUSEADDR, (void*) &optVal, optLen); - - if (sockfd != -1) - close(sockfd); - - if (sockfd1 != -1) - close(sockfd1); - - unlink(SERVER_PATH); + printf("Usage:\n"); + for (int i = 0; i < sizeof(kSupportedCommands) + / sizeof(kSupportedCommands[0]); i++) { + printf(" %16s - %s\n", kSupportedCommands[i].command, kSupportedCommands[i].help); + } } diff --git a/src/Ntk-Console/Netsukuku-Console.h b/src/Ntk-Console/Netsukuku-Console.h index e81142d..9d7059f 100644 --- a/src/Ntk-Console/Netsukuku-Console.h +++ b/src/Ntk-Console/Netsukuku-Console.h @@ -12,10 +12,34 @@ #include #include -#define SERVER_PATH "/tmp/ntk-console" -#define BUFFER_LENGTH 250 -#define VERSION_STR "0.0.2" -#define FALSE 0 + +#define SERVER_PATH "/tmp/ntk-console" +#define BUFFER_LENGTH 250 +#define VERSION_STR "0.0.2" + +#ifndef TRUE +#define FALSE 0 +#define TRUE 1 +#endif + + +typedef enum { + COMMAND_HELP = 0x100, + COMMAND_UPTIME, + COMMAND_KILL, + COMMAND_VERSION, + COMMAND_INETCONN, + COMMAND_CURIFS, + COMMAND_CURIFSCT, + COMMAND_CURQSPNID, + COMMAND_CURIP, + COMMAND_CURNODE, + COMMAND_IFS, + COMMAND_IFSCT, + COMMAND_QUIT, + COMMAND_CONSUPTIME, +} command_t; + int sockfd = -1, sockfd1 = -1; struct sockaddr_un serveraddr; @@ -33,4 +57,11 @@ int uptime_year; int i; -#endif /*NETSUKUKUCONSOLE_H*/ \ No newline at end of file +void usage(); +void clean_up(); + +void opensocket(); +void closesocket(); + + +#endif /*NETSUKUKUCONSOLE_H*/ diff --git a/src/ntk-console-bindings.c b/src/ntk-console-bindings.c index e1d6de1..403c29a 100644 --- a/src/ntk-console-bindings.c +++ b/src/ntk-console-bindings.c @@ -9,9 +9,10 @@ /* Constants used for the console bindings. */ -#define SERVER_PATH "/tmp/ntk-console" +#define SERVER_PATH "/tmp/ntk-console" #define REQUEST_LENGTH 250 -#define FALSE 0 +#define FALSE 0 +#define TRUE 1 /* Variable and structure defintions, sockfd refers to socket file descriptor * length refers to the required length of the requests that will be sent. @@ -28,181 +29,167 @@ int rc, length; * unlinks the server path, etc. */ void clean_up(void) { - - const int optVal = 1; - const socklen_t optLen = sizeof(optVal); - - setsockopt(sockfd_1, SOL_SOCKET, SO_REUSEADDR, (void*) &optVal, optLen); - setsockopt(sockfd_2, SOL_SOCKET, SO_REUSEADDR, (void*) &optVal, optLen); - - if (sockfd_1 != -1) - close(sockfd_1); + + const int optVal = 1; + const socklen_t optLen = sizeof(optVal); + + setsockopt(sockfd_1, SOL_SOCKET, SO_REUSEADDR, (void*) &optVal, optLen); + setsockopt(sockfd_2, SOL_SOCKET, SO_REUSEADDR, (void*) &optVal, optLen); + + if (sockfd_1 != -1) + close(sockfd_1); - if (sockfd_2 != -1) - close(sockfd_2); + if (sockfd_2 != -1) + close(sockfd_2); unlink(SERVER_PATH); - + } /* Creates an AF_UNIX socket and binds it to a local address. */ void opensocket(void) { - - int stop_trying; - - sockfd_1 = socket(AF_UNIX, SOCK_STREAM, 0); - if (sockfd_1 < 0) { - perror("socket creation failed"); - exit(-1); - } - - memset(&serveraddr, 0, sizeof(serveraddr)); - serveraddr.sun_family = AF_UNIX; - strcpy(serveraddr.sun_path, SERVER_PATH); + + int stop_trying; + + sockfd_1 = socket(AF_UNIX, SOCK_STREAM, 0); + if (sockfd_1 < 0) { + perror("socket creation failed"); + exit(-1); + } + + memset(&serveraddr, 0, sizeof(serveraddr)); + serveraddr.sun_family = AF_UNIX; + strcpy(serveraddr.sun_path, SERVER_PATH); - rc = bind(sockfd_1, (struct sockaddr *)&serveraddr, SUN_LEN(&serveraddr)); - if (rc < 0) { - perror("bind() failed"); - clean_up(); - if(stop_trying >= 2) { - perror("bind() failed"); - clean_up(); - opensocket(); - exit(-1); - } - stop_trying++; - opensocket(); - } + rc = bind(sockfd_1, (struct sockaddr *)&serveraddr, SUN_LEN(&serveraddr)); + if (rc < 0) { + perror("bind() failed"); + clean_up(); + if(stop_trying >= 2) { + perror("bind() failed"); + clean_up(); + opensocket(); + exit(-1); + } + stop_trying++; + opensocket(); + } } /* Sends a parsed response to the ntk console client. */ -void send_response(char response[REQUEST_LENGTH], ...) { - int response_length; - - response_length = (int)strlen(response); - memset(response, 'a', REQUEST_LENGTH - response_length); - rc = send(sockfd_2, response, sizeof(response), 0); - if (rc < 0){ - perror("send() failed"); - exit(-1); - } - +void +send_response(char response[REQUEST_LENGTH], ...) +{ + int response_length = (int)strlen(response); + rc = send(sockfd_2, response, sizeof(response), 0); + if (rc < 0){ + perror("send() failed"); + exit(-1); + } } -void request_cleanup(char unprocessed_request[REQUEST_LENGTH]) { - - char remove = 'a'; - - char* c; - int x; - char* pPosition; - while(pPosition = strchr(unprocessed_request, 'a') != NULL) { - if ((c = index(unprocessed_request, remove)) != NULL) { - size_t len_left = sizeof(unprocessed_request) - (c+1-unprocessed_request); - memmove(c, c+1, len_left); - } - } - printf("Cleaned Request is: %s", unprocessed_request); - - request_processing(unprocessed_request); - -} /* Parses the received request from the ntk console client * to data from ntkd structures such as: me * into a response for the ntk console client. */ -int request_processing(char unprocessed_request[REQUEST_LENGTH]) { - - if(strncmp(unprocessed_request,"uptime", (int)strlen(unprocessed_request)) == 0) - send_response((char)time(0)-me.uptime); - - else if(strncmp(unprocessed_request,"version", (int)strlen(unprocessed_request)) == 0) - send_response(VERSION_STR); - - else if(strncmp(unprocessed_request,"inet_connected", (int)strlen(unprocessed_request)) == 0) - send_response((char)me.inet_connected); - - else if(strncmp(unprocessed_request,"cur_ifs", (int)strlen(unprocessed_request)) == 0) - send_response((char)me.cur_ifs); - - else if(strncmp(unprocessed_request,"cur_ifs_n", (int)strlen(unprocessed_request)) == 0) - send_response((char)me.cur_ifs_n); - - else if(strncmp(unprocessed_request,"cur_qspn_id", (int)strlen(unprocessed_request)) == 0) - send_response((char)me.cur_qspn_id); - - else if(strncmp(unprocessed_request,"cur_ip", (int)strlen(unprocessed_request)) == 0) - send_response((char)me.cur_ip.data); - - /*else if(strncmp(unprocessed_request,"cur_node", (int)strlen(unprocessed_request)) == 0) - send_response(me.cur_node); - - else if(strncmp(unprocessed_request,"ifs", (int)strlen(unprocessed_request)) == 0) - return 0; - - else if(strncmp(unprocessed_request,"ifs_n", (int)strlen(unprocessed_request)) == 0) - return 0;*/ - send_response(unprocessed_request, " Is invalid or yet to be implemented."); - return -1; +int +request_processing(char unprocessed_request[REQUEST_LENGTH]) +{ + if(strncmp(unprocessed_request,"uptime", (int)strlen(unprocessed_request)) == 0) + send_response((char)time(0)-me.uptime); + + else if(strncmp(unprocessed_request,"version", (int)strlen(unprocessed_request)) == 0) + send_response(VERSION_STR); + + else if(strncmp(unprocessed_request,"inet_connected", (int)strlen(unprocessed_request)) == 0) + send_response((char)me.inet_connected); + + else if(strncmp(unprocessed_request,"cur_ifs", (int)strlen(unprocessed_request)) == 0) + send_response((char)me.cur_ifs); + + else if(strncmp(unprocessed_request,"cur_ifs_n", (int)strlen(unprocessed_request)) == 0) + send_response((char)me.cur_ifs_n); + + else if(strncmp(unprocessed_request,"cur_qspn_id", (int)strlen(unprocessed_request)) == 0) + send_response((char)me.cur_qspn_id); + + else if(strncmp(unprocessed_request,"cur_ip", (int)strlen(unprocessed_request)) == 0) + send_response((char)me.cur_ip.data); + + /*else if(strncmp(unprocessed_request,"cur_node", (int)strlen(unprocessed_request)) == 0) + send_response(me.cur_node); + + else if(strncmp(unprocessed_request,"ifs", (int)strlen(unprocessed_request)) == 0) + return 0; + + else if(strncmp(unprocessed_request,"ifs_n", (int)strlen(unprocessed_request)) == 0) + return 0;*/ + send_response(unprocessed_request, " Is invalid or yet to be implemented."); + return -1; } -/* Receives a request of 250 bytes from the ntk console client. - * listen and accept are also in a while loop to allow for different - * start times between the ntk console bindings and the ntk console client, - * As well as restarting of the ntk console client. */ -void ntkd_request(void) { - - char request[REQUEST_LENGTH]; - - do { - - rc = listen(sockfd_1, 10); - if (rc< 0) { - perror("listen() failed"); - exit(-1); - } - printf("Ready for client connect().\n"); - - sockfd_2 = accept(sockfd_1, NULL, NULL); - if (sockfd_2 < 0) { - perror("accept() failed"); - exit(-1); - } - - length = REQUEST_LENGTH; - rc = setsockopt(sockfd_2, SOL_SOCKET, SO_RCVLOWAT, - (char *)&length, sizeof(length)); - if (rc < 0) { - perror("setsockopt(SO_RCVLOWAT) failed"); - exit(-1); - } - - rc = recv(sockfd_2, request, sizeof(request), 0); - if (rc < 0) { - perror("recv() failed"); - exit(-1); - } - - printf("%d bytes of data were received\n", rc); - - if (rc == 0 || rc < sizeof(request)) { - printf("The console client closed the connection before all of the\n"); - printf("data was sent\n"); - exit(-1); - } - - request_cleanup(request); - } while(FALSE); - - clean_up(); - +static int +request_receive(int sock, char message[], int max) +{ + int total = 0; + const int bsize = 1024; + char buffer[bsize+1]; + int read = bsize; + + message[0] = 0; // initialize for strcat() + + while(read == bsize) { + read = recv(sock, buffer, bsize, 0); + if(read < 0) + return -1; // error, bail out + total += read; + if(total > max) + return -2; // overflow + buffer[read] = 0; + strcat(message, buffer); + } + + return total; +} + + +void ntkd_request(void) { + char request[REQUEST_LENGTH]; + + rc = listen(sockfd_1, 10); + if (rc< 0) { + perror("listen() failed"); + exit(-1); + } + + printf("Ready for client connect().\n"); + + do { + sockfd_2 = accept(sockfd_1, NULL, NULL); + if (sockfd_2 < 0) { + perror("accept() failed"); + exit(-1); + } + + rc = request_receive(sockfd_2, request, REQUEST_LENGTH); + if (rc < 0) { + perror("recv() failed"); + exit(-1); + } + + printf("%d bytes of data were received\n", rc); + + request_processing(request); + } while(TRUE); + + clean_up(); } void console_recv_send(void) { - opensocket(); - ntkd_request(); -} \ No newline at end of file + opensocket(); + ntkd_request(); +}