Hi,
I am creating a socket application that requires connecting a MySQL database.
Basically, I am accepting a socket, forking the process, then calling a method to perform user authentication. Everything works fine, however, if I manually break the connection on the client end, the programs runs into an infinite loop.
The code is listed below:
server.c
Code:
#include <stdio.h>
#include "server.h"
#include "prompt.h"
#include "single_transaction.h"
#include "logging.h"
#include <signal.h>
#include "permissions.h"
void initChild(int client, SSL_CTX* ctx);
void error(const char *msg) {
perror(msg);
exit(1);
}
int main(int count, char *strings[])
{ SSL_CTX *ctx;
int server, client_sockfd;
char *portnum;
int pid;
if ( count != 2 )
{
printf("Usage: %s <portnum>\n", strings[0]);
exit(0);
}
SSL_library_init();
portnum = strings[1];
ctx = InitServerCTX(); /* initialize SSL */
LoadCertificates(ctx, "../keys/mycert.pem", "../keys/server.key"); /* load certs */
server = OpenListener(atoi(portnum));
struct sockaddr_in addr;
int len = sizeof(addr);
signal(SIGCHLD, SIG_IGN); /* Prevent zombie processes */
while (1) {
if ((client_sockfd = accept(server,(struct sockaddr *)&addr,&len)) == -1) {
/** accept error **/
exit(1);
}
if (!(pid = fork())) {
/** Child keeps communicating here **/
initChild(client_sockfd, ctx);
/** Now Child Exits **/
shutdown(client_sockfd,2);
close(client_sockfd);
}
/** if forked successfully **/
//close(client_sockfd ); /* Causes socket to close - the socket should be closed by the client */
} /** while waiting for hits on port **/
close(server);
SSL_CTX_free(ctx);
return 0;
}
void initChild(int client, SSL_CTX* ctx) {
int sd, response, n;
char action[255];
int bufsize = 1024;
char* buf = (char *)malloc(1024*sizeof(char));
SSL ........l;
ssl = SSL_new(ctx); /* get new SSL state with context */
SSL_set_fd(ssl, client); /* set connection socket to SSL state */
if ( SSL_accept(ssl) == FAIL ) /* do SSL-protocol accept */
ERR_print_errors_fp(stderr);
else
{
if(authenticate_client("ethanhayon", "password")) {
while (1)
{
write_menu(ssl);
printf("Action: %d\n", getAction(ssl));
}
}
}
/* clean up */
free(buf);
sd = SSL_get_fd(ssl); /* get socket connection */
SSL_free(ssl); /* release SSL state */
close(sd);
/* close connection */
}
permissions.h
Code:
#include <my_global.h>
#include <mysql.h>
#ifndef _PERMISSIONS_H_
#define _PERMISSIONS_H_
int authenticate_client(char * username, char * password) {
MYSQL *conn;
MYSQL_RES *result;
int num_rows;
char* query = (char *)malloc(1024*sizeof(char));
conn = mysql_init(NULL);
if (!(mysql_real_connect(conn, "localhost", "user", "pass", "db_name", 0, NULL, 0))) {
printf("Error connecting to database");
// exit gracefully
} else {
sprintf(query, "SELECT * FROM permissions WHERE username='%s' AND password = '%s'", username, password);
mysql_query(conn, "SELECT * FROM permissions WHERE username = 'ethanhayon'");
result = mysql_store_result(conn);
num_rows = mysql_num_rows(result);
}
// clean up...
mysql_free_result(result);
mysql_close(conn);
free(query);
return 1;
}
Any help is appreciated!
Thank you!
- Ethan
EDIT: I know the code is messy, I'm still in the debugging phase...