/**
* Group : Edison Chindrawaly
*
Sehoon Jung
* Sangtae Park
*
* Project: #1 Crypto Server
*/
#include "crypt_server.h"
void
main()
{
int listenfd;
MESSAGE message;
listenfd = openConnection(askPort());
beginProcess(listenfd);
closeConnection(listenfd);
}
/**
* openConnection's method is to establish
connection
* between the client
and host.
* @param int PORT contains predefine port
number
* @return sockfd if flag ==
1 else connfd is return
*/
int
openConnection(int PORT)
{
int servsize;
int yes
= 1;
int
sockfd,connfd,clientsize;
struct
sockaddr_in my_add;
struct
sockaddr_in other_add;
sockfd = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
verify(0,sockfd,socket_flag);
bzero(&(my_add.sin_zero),sizeof(my_add));
my_add.sin_family = AF_INET;
my_add.sin_port = htons(PORT);
my_add.sin_addr.s_addr = INADDR_ANY;
verify(sockfd,
bind(sockfd,(struct sockaddr *)&my_add, sizeof(struct
sockaddr)),
bind_flag);
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(int));
verify(sockfd,listen(sockfd,BACKLOG),listen_flag);
return sockfd;
}
/**
* beginProcess's method is where the process
is being
* execute - send/receive
messages. It receives a listen socket
* descriptors. It accepts more than 2 connections from 2 or
* more clients. Right now I specify the max
number of client
* to be 5
clients.
* @param int sockfd contain socket descriptors
* @return none
*/
void beginProcess(int sockfd)
{
int byteRecv = 0;
int byteSend = 0;
int encrypt = 1;
int decrypt = 2;
char* tmp;
MESSAGE message;
int
new_sock = 0;
int fd[2];
struct sockaddr_in other_add;
int clisize = sizeof(other_add);
verify(sockfd,pipe(fd),pipe_flag);
fd_set readfds, master;
FD_ZERO(&readfds);
FD_ZERO(&master);
FD_SET(STDIN,&master);
FD_SET(sockfd,&master);
FD_SET(fd[READ],&master);
printf("Press any key to
terminate\n");
while(true)
{
readfds = master;
verify(sockfd,
select(FD_SETSIZE,&readfds,NULL,NULL,NULL),
select_flag);
if(FD_ISSET(STDIN,&readfds))
{
printf("crypt_server terminates\n");
break;
} // end to detect the keyboard
if(FD_ISSET(sockfd,&readfds))
{
new_sock = accept(sockfd,(struct sockaddr *)&other_add,
(socklen_t
*)&clisize);
printf("Receive connection from:
%s\n",inet_ntoa(other_add.sin_addr));
if(fork() == 0)
{
close(sockfd);
do
{
byteRecv =
receivedStruct(new_sock,message);
verify(new_sock,byteRecv,receive_flag);
printf("Receive msg %s: %s\n",
inet_ntoa(other_add.sin_addr),
message.msg);
if(message.option ==
encrypt)
tmp =
strdup(encryptDecrypt(message.msg,message.key,encrypt));
else
tmp = strdup(encryptDecrypt(message.msg,message.key,decrypt));
if((strcasecmp(message.msg,"END") == 0) ||
(strcasecmp(tmp,"END") ==
0))
{
message.msg_length = strlen(tmp);
strcpy(message.msg,tmp);
byteSend =
sendStruct(new_sock,message);
verify(new_sock,byteSend,send_flag);
printf("Terminate:
%s\n",inet_ntoa(other_add.sin_addr));
break;
}
strcpy(message.msg,tmp);
printf("Send msg to %s:
%s\n",inet_ntoa(other_add.sin_addr),
message.msg);
byteSend = sendStruct(new_sock,message);
verify(new_sock,byteSend,send_flag);
}while(byteRecv > 0);
close(new_sock);
exit(0);
} // end child
FD_CLR(new_sock,&readfds);
close(new_sock);
} // end
to detect the socket
} //
end of while - loop
}// end of beginProcess.
/**
* verify's method is to verify whether the
operation is successful
*
@param int sock contains socket
descriptor
* int byte contains the byte to
check
* int flag contains the operation type
* @return none
*/
void verify(int sockfd, int byte, int
flag)
{
switch(flag)
{
case
0:if(byte<0)
{
perror("ERROR: socket has
failed\n");
exit(0);
}
break;
case 1:if(byte<0)
{
perror("ERROR: bind has failed\n");
closeConnection(sockfd);
exit(0);
}
break;
case
2:if(byte<0)
{
perror("ERROR: listen has
failed\n");
closeConnection(sockfd);
exit(0);
}
break;
case
3:if(byte<0)
{
perror("ERROR: accept has
failed\n");
closeConnection(sockfd);
exit(0);
}
break;
case 4:if(byte<0)
{
perror("ERROR: send has failed\n");
closeConnection(sockfd);
exit(0);
}
break;
case
5:if(byte<0)
{
perror("ERROR: receive has
failed\n");
closeConnection(sockfd);
exit(0);
}
break;
case 6:if(byte<0)
{
perror("ERROR: pipe has failed\n");
exit(0);
}
break;
case
7:if(byte<0)
{
perror("ERROR: write has
failed\n");
exit(0);
}
break;
case 8:if(byte<0)
{
perror("ERROR: read has failed\n");
exit(0);
}
break;
case
9:if(byte<0)
{
perror("ERROR: select has
failed\n");
exit(0);
}
default: break;
}
}
/**
* receivedStruct's method is to receive
struct from
* the given socket. It
will return -1 if it fails
* to
receive otherwise it will return int bigger than
* zero.
* @param int sockfd
contains sock descriptor
* struct MSG contains the struct itself
* @return int
*/
int receivedStruct(int sockfd,
MESSAGE& receivedMsg)
{
int byteRecv = 0;
byteRecv
= recv(sockfd,(char *)&receivedMsg,sizeof(MESSAGE),0);
return byteRecv;
}
/**
* sendStruct's method is to send MESSAGE
struct to the client/
* server
that is address by the socket descriptor
* @param int sockfd
contains socket descriptor
* MESSAGE msg contains the message
struct
* @return -1 if fail
otherwiser return number of bytes send
*/
int sendStruct(int sockfd, MESSAGE msg)
{
int numSend = 0;
numSend = send(sockfd,(char *)&msg,
sizeof(MESSAGE),0);
return
numSend;
}
/**
*
encryptDecrypt's method is to encrypt or decrypt
* a message that is pass into the
method.
* @param char* msg contains the message
*
char key contains the key to encrypt/decrypt
*
int flag contains
* 1 - to encrypt the message
*
2 - to decrypt the message
* @return the encrypted/decrypted message
*/
char* encryptDecrypt(char* msg, char
key, int flag)
{
char buf[MAXSIZE];
if((msg == NULL) || (strlen(msg)<1))
return NULL;
int length = strlen(msg);
switch(flag)
{
case 1: // encrypt
message
for(int i = 0;
i<length; i++)
buf[i]
= msg[i] + key;
break;
case 2: // decrypt
message
for(int i = 0;
i<length; i++)
buf[i]
= msg[i] - key;
break;
default:
return NULL;
}
buf[length] = '\0';
char* buffer = strdup(buf);
return buffer;
}
/**
* closeConnection's method is to close the
socket
* descriptor that contains
the connection of
* the
client/server's model
*
@param int sockfd contains socket
descriptor
* @return none
*/
void closeConnection(int
sockfd)
{
close(sockfd);
}
int askPort()
{
int port;
cout<<"enter port: ";
cin>>port;
cout<<flush;
return port;
}