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

View File

@ -14,14 +14,14 @@
#define FALSE 0
#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.
* recv won't wake up until length is received.
* rc is used for error checking in socket operations.
* serveraddr is a structure describing the address of
* an AF_LOCAL (aka AF_UNIX) socket. */
int sockfd_1 = -1, sockfd_2 = -1;
int serverfd = -1;
struct sockaddr_un serveraddr;
int rc, length;
@ -33,15 +33,11 @@ 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);
setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, (void*) &optVal, optLen);
if (sockfd_1 != -1)
close(sockfd_1);
if (serverfd != -1)
close(serverfd);
if (sockfd_2 != -1)
close(sockfd_2);
unlink(SERVER_PATH);
}
@ -52,8 +48,8 @@ void opensocket(void) {
int stop_trying;
sockfd_1 = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd_1 < 0) {
serverfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (serverfd < 0) {
perror("socket creation failed");
exit(-1);
}
@ -62,7 +58,7 @@ void opensocket(void) {
serveraddr.sun_family = AF_UNIX;
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) {
perror("bind() failed");
clean_up();
@ -80,10 +76,10 @@ void opensocket(void) {
/* Sends a parsed response to the ntk console client. */
void
send_response(char response[REQUEST_LENGTH], ...)
send_response(int session_fd, char response[REQUEST_LENGTH], ...)
{
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){
perror("send() failed");
exit(-1);
@ -96,28 +92,28 @@ send_response(char response[REQUEST_LENGTH], ...)
* into a response for the ntk console client. */
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)
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)
send_response(VERSION_STR);
send_response(session_fd, VERSION_STR);
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)
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)
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)
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)
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)
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)
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;
}
@ -157,10 +153,10 @@ request_receive(int sock, char message[], int max)
}
void ntkd_request(void) {
char request[REQUEST_LENGTH];
rc = listen(sockfd_1, 10);
void
wait_session(int server_fd)
{
rc = listen(serverfd, 10);
if (rc< 0) {
perror("listen() failed");
exit(-1);
@ -168,28 +164,49 @@ void ntkd_request(void) {
printf("Ready for client connect().\n");
do {
sockfd_2 = accept(sockfd_1, NULL, NULL);
if (sockfd_2 < 0) {
for(;;) {
int session_fd = accept(server_fd, NULL, NULL);
if (session_fd < 0) {
perror("accept() failed");
exit(-1);
}
rc = request_receive(sockfd_2, request, REQUEST_LENGTH);
if (rc < 0) {
perror("recv() failed");
pid_t pid = fork();
if (pid == -1) {
perror("Failed to spawn child console process");
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) {
opensocket();
ntkd_request();
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();
wait_session(serverfd);
}