Ntk-console: Clean up file descriptors.

* Fork incomming console connections to support
  multiple connections at once.
* Rework ntpd console connection acceptance.
This commit is contained in:
Alexander von Gluck IV 2014-09-14 10:40:39 -05:00
parent bc3f496788
commit 0a5463d759
2 changed files with 71 additions and 56 deletions

View File

@ -4,9 +4,6 @@
#include <unistd.h> #include <unistd.h>
char response[BUFFER_LENGTH];
const struct supported_commands { const struct supported_commands {
command_t id; command_t id;
const char* command; const char* command;
@ -95,13 +92,14 @@ ntkd_request(char *request)
exit(-1); exit(-1);
} }
char response[BUFFER_LENGTH];
request_receive(sockfd, response, BUFFER_LENGTH); request_receive(sockfd, response, BUFFER_LENGTH);
if (rc < 0) { if (rc < 0) {
perror("recv() failed"); perror("recv() failed");
exit(-1); exit(-1);
} }
printf("%s\n", response); printf("Response: %s\n", response);
} }
@ -121,6 +119,7 @@ opensocket(void)
rc = connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)); rc = connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
if (rc < 0) { if (rc < 0) {
perror("connect() failed"); perror("connect() failed");
printf("Unable to connect to ntk daemon console.\n");
exit(-1); exit(-1);
} }
printf("ntkd console connection opened successfully.\n"); printf("ntkd console connection opened successfully.\n");
@ -193,6 +192,7 @@ console(char* request)
case COMMAND_QUIT: case COMMAND_QUIT:
closesocket(); closesocket();
exit(0); exit(0);
break;
case COMMAND_UPTIME: case COMMAND_UPTIME:
case COMMAND_INETCONN: case COMMAND_INETCONN:
case COMMAND_CURIFS: case COMMAND_CURIFS:
@ -237,21 +237,19 @@ main(void)
uptime_month = timeinfo->tm_mon; uptime_month = timeinfo->tm_mon;
uptime_year = timeinfo->tm_year; uptime_year = timeinfo->tm_year;
printf("This is the Netsukuku Console, Please type 'help' for more information.\n");
char* request = (char*)malloc(BUFFER_LENGTH);
opensocket(); opensocket();
do {
printf("This is the Netsukuku Console. Please type 'help' for more information.\n");
for(;;) {
char* request = (char*)malloc(BUFFER_LENGTH);
printf("\n> "); printf("\n> ");
fgets(request, 16, stdin); fgets(request, 16, stdin);
fflush(stdin); fflush(stdin);
console(request); console(request);
memset(request, 0, BUFFER_LENGTH); free(request);
} while(TRUE); }
closesocket(); closesocket();
clean_up();
return 0; return 0;
} }

View File

@ -14,14 +14,14 @@
#define FALSE 0 #define FALSE 0
#define TRUE 1 #define TRUE 1
/* Variable and structure defintions, sockfd refers to socket file descriptor /* Variable and structure defintions, serverfd refers to socket file descriptor
* length refers to the required length of the requests that will be sent. * length refers to the required length of the requests that will be sent.
* recv won't wake up until length is received. * recv won't wake up until length is received.
* rc is used for error checking in socket operations. * rc is used for error checking in socket operations.
* serveraddr is a structure describing the address of * serveraddr is a structure describing the address of
* an AF_LOCAL (aka AF_UNIX) socket. */ * an AF_LOCAL (aka AF_UNIX) socket. */
int sockfd_1 = -1, sockfd_2 = -1; int serverfd = -1;
struct sockaddr_un serveraddr; struct sockaddr_un serveraddr;
int rc, length; int rc, length;
@ -33,14 +33,10 @@ void clean_up(void) {
const int optVal = 1; const int optVal = 1;
const socklen_t optLen = sizeof(optVal); const socklen_t optLen = sizeof(optVal);
setsockopt(sockfd_1, SOL_SOCKET, SO_REUSEADDR, (void*) &optVal, optLen); setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, (void*) &optVal, optLen);
setsockopt(sockfd_2, SOL_SOCKET, SO_REUSEADDR, (void*) &optVal, optLen);
if (sockfd_1 != -1) if (serverfd != -1)
close(sockfd_1); close(serverfd);
if (sockfd_2 != -1)
close(sockfd_2);
unlink(SERVER_PATH); unlink(SERVER_PATH);
@ -52,8 +48,8 @@ void opensocket(void) {
int stop_trying; int stop_trying;
sockfd_1 = socket(AF_UNIX, SOCK_STREAM, 0); serverfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd_1 < 0) { if (serverfd < 0) {
perror("socket creation failed"); perror("socket creation failed");
exit(-1); exit(-1);
} }
@ -62,7 +58,7 @@ void opensocket(void) {
serveraddr.sun_family = AF_UNIX; serveraddr.sun_family = AF_UNIX;
strcpy(serveraddr.sun_path, SERVER_PATH); strcpy(serveraddr.sun_path, SERVER_PATH);
rc = bind(sockfd_1, (struct sockaddr *)&serveraddr, SUN_LEN(&serveraddr)); rc = bind(serverfd, (struct sockaddr *)&serveraddr, SUN_LEN(&serveraddr));
if (rc < 0) { if (rc < 0) {
perror("bind() failed"); perror("bind() failed");
clean_up(); clean_up();
@ -80,10 +76,10 @@ void opensocket(void) {
/* Sends a parsed response to the ntk console client. */ /* Sends a parsed response to the ntk console client. */
void void
send_response(char response[REQUEST_LENGTH], ...) send_response(int session_fd, char response[REQUEST_LENGTH], ...)
{ {
int response_length = (int)strlen(response); int response_length = (int)strlen(response);
rc = send(sockfd_2, response, sizeof(response), 0); rc = send(session_fd, response, response_length, 0);
if (rc < 0){ if (rc < 0){
perror("send() failed"); perror("send() failed");
exit(-1); exit(-1);
@ -96,28 +92,28 @@ send_response(char response[REQUEST_LENGTH], ...)
* into a response for the ntk console client. */ * into a response for the ntk console client. */
int int
request_processing(char unprocessed_request[REQUEST_LENGTH]) request_processing(int session_fd, char unprocessed_request[REQUEST_LENGTH])
{ {
if(strncmp(unprocessed_request,"uptime", (int)strlen(unprocessed_request)) == 0) if(strncmp(unprocessed_request,"uptime", (int)strlen(unprocessed_request)) == 0)
send_response((char)time(0)-me.uptime); send_response(session_fd, (char)time(0)-me.uptime);
else if(strncmp(unprocessed_request,"version", (int)strlen(unprocessed_request)) == 0) else if(strncmp(unprocessed_request,"version", (int)strlen(unprocessed_request)) == 0)
send_response(VERSION_STR); send_response(session_fd, VERSION_STR);
else if(strncmp(unprocessed_request,"inet_connected", (int)strlen(unprocessed_request)) == 0) else if(strncmp(unprocessed_request,"inet_connected", (int)strlen(unprocessed_request)) == 0)
send_response((char)me.inet_connected); send_response(session_fd, (char)me.inet_connected);
else if(strncmp(unprocessed_request,"cur_ifs", (int)strlen(unprocessed_request)) == 0) else if(strncmp(unprocessed_request,"cur_ifs", (int)strlen(unprocessed_request)) == 0)
send_response((char)me.cur_ifs); send_response(session_fd, (char)me.cur_ifs);
else if(strncmp(unprocessed_request,"cur_ifs_n", (int)strlen(unprocessed_request)) == 0) else if(strncmp(unprocessed_request,"cur_ifs_n", (int)strlen(unprocessed_request)) == 0)
send_response((char)me.cur_ifs_n); send_response(session_fd, (char)me.cur_ifs_n);
else if(strncmp(unprocessed_request,"cur_qspn_id", (int)strlen(unprocessed_request)) == 0) else if(strncmp(unprocessed_request,"cur_qspn_id", (int)strlen(unprocessed_request)) == 0)
send_response((char)me.cur_qspn_id); send_response(session_fd, (char)me.cur_qspn_id);
else if(strncmp(unprocessed_request,"cur_ip", (int)strlen(unprocessed_request)) == 0) else if(strncmp(unprocessed_request,"cur_ip", (int)strlen(unprocessed_request)) == 0)
send_response((char)me.cur_ip.data); send_response(session_fd, (char)me.cur_ip.data);
/*else if(strncmp(unprocessed_request,"cur_node", (int)strlen(unprocessed_request)) == 0) /*else if(strncmp(unprocessed_request,"cur_node", (int)strlen(unprocessed_request)) == 0)
send_response(me.cur_node); send_response(me.cur_node);
@ -127,7 +123,7 @@ request_processing(char unprocessed_request[REQUEST_LENGTH])
else if(strncmp(unprocessed_request,"ifs_n", (int)strlen(unprocessed_request)) == 0) else if(strncmp(unprocessed_request,"ifs_n", (int)strlen(unprocessed_request)) == 0)
return 0;*/ return 0;*/
send_response(unprocessed_request, " Is invalid or yet to be implemented."); send_response(session_fd, unprocessed_request, " Is invalid or yet to be implemented.");
return -1; return -1;
} }
@ -157,10 +153,10 @@ request_receive(int sock, char message[], int max)
} }
void ntkd_request(void) { void
char request[REQUEST_LENGTH]; wait_session(int server_fd)
{
rc = listen(sockfd_1, 10); rc = listen(serverfd, 10);
if (rc< 0) { if (rc< 0) {
perror("listen() failed"); perror("listen() failed");
exit(-1); exit(-1);
@ -168,28 +164,49 @@ void ntkd_request(void) {
printf("Ready for client connect().\n"); printf("Ready for client connect().\n");
do { for(;;) {
sockfd_2 = accept(sockfd_1, NULL, NULL); int session_fd = accept(server_fd, NULL, NULL);
if (sockfd_2 < 0) { if (session_fd < 0) {
perror("accept() failed"); perror("accept() failed");
exit(-1); exit(-1);
} }
rc = request_receive(sockfd_2, request, REQUEST_LENGTH); pid_t pid = fork();
if (rc < 0) { if (pid == -1) {
perror("recv() failed"); perror("Failed to spawn child console process");
exit(-1); exit(-1);
} else if (pid == 0) {
close(server_fd);
handle_session(session_fd);
_exit(0);
} else {
close(session_fd);
} }
printf("%d bytes of data were received\n", rc); }
request_processing(request);
} while(TRUE);
clean_up();
} }
void console_recv_send(void) {
void
handle_session(int session_fd)
{
char request[REQUEST_LENGTH];
rc = request_receive(session_fd, request, REQUEST_LENGTH);
if (rc < 0) {
perror("recv() failed");
exit(-1);
}
printf("%d bytes of data were received\n", rc);
request_processing(session_fd, request);
}
void
console_recv_send(void)
{
opensocket(); opensocket();
ntkd_request(); wait_session(serverfd);
} }