|
|
|
@ -35,9 +35,9 @@
|
|
|
|
|
/**** types *******************************************************************
|
|
|
|
|
*******************************************************************************/
|
|
|
|
|
struct tcp_conn_handler_data{
|
|
|
|
|
struct sockaddr_in *address;
|
|
|
|
|
struct socket *accept_socket;
|
|
|
|
|
int thread_id;
|
|
|
|
|
struct sockaddr_in *FAddress;
|
|
|
|
|
struct socket *FAcceptSocket;
|
|
|
|
|
int FThreadID;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct tcp_conn_handler{
|
|
|
|
@ -46,144 +46,146 @@ struct tcp_conn_handler{
|
|
|
|
|
int tcp_conn_handler_stopped[MAX_CONNS];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct tcp_conn_handler *tcp_conn_handler;
|
|
|
|
|
struct tcp_conn_handler *STCPConnHandler;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct tcp_server_service{
|
|
|
|
|
int running;
|
|
|
|
|
struct socket *listen_socket;
|
|
|
|
|
struct task_struct *thread;
|
|
|
|
|
struct task_struct *accept_thread;
|
|
|
|
|
int FRunning;
|
|
|
|
|
struct socket *FListenSocket;
|
|
|
|
|
struct task_struct *FThread;
|
|
|
|
|
struct task_struct *FAccpeptThread;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct tcp_server_service *tcp_server;
|
|
|
|
|
struct tcp_server_service *FTCPServer_Service;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**** var **********************************************************************
|
|
|
|
|
*******************************************************************************/
|
|
|
|
|
int tcp_listener_stopped = 0;
|
|
|
|
|
int tcp_acceptor_stopped = 0;
|
|
|
|
|
static int STCPListenerStopped = 0;
|
|
|
|
|
static int STCPAcceptorStopped = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
char *inet_ntoa(struct in_addr *in){
|
|
|
|
|
char *str_ip = NULL;
|
|
|
|
|
u_int32_t int_ip = 0;
|
|
|
|
|
char *inet_ntoa(struct in_addr *AInAddr){
|
|
|
|
|
char *LIPAddr = NULL;
|
|
|
|
|
u_int32_t LIPInt = 0;
|
|
|
|
|
|
|
|
|
|
str_ip = kmalloc(16 * sizeof(char), GFP_KERNEL);
|
|
|
|
|
LIPAddr = kmalloc(16 * sizeof(char), GFP_KERNEL);
|
|
|
|
|
|
|
|
|
|
if(!str_ip)
|
|
|
|
|
if(!LIPAddr)
|
|
|
|
|
return NULL;
|
|
|
|
|
else
|
|
|
|
|
memset(str_ip, 0, 16);
|
|
|
|
|
memset(LIPAddr, 0, 16);
|
|
|
|
|
|
|
|
|
|
int_ip = in->s_addr;
|
|
|
|
|
LIPInt = AInAddr->s_addr;
|
|
|
|
|
|
|
|
|
|
sprintf(str_ip, "%d.%d.%d.%d", (int_ip) & 0xFF, (int_ip >> 8) & 0xFF,
|
|
|
|
|
(int_ip >> 16) & 0xFF, (int_ip >> 16) & 0xFF);
|
|
|
|
|
sprintf(LIPAddr, "%d.%d.%d.%d", (LIPInt) & 0xFF, (LIPInt >> 8) & 0xFF,
|
|
|
|
|
(LIPInt >> 16) & 0xFF, (LIPInt >> 16) & 0xFF);
|
|
|
|
|
|
|
|
|
|
return str_ip;
|
|
|
|
|
return LIPAddr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int tcp_server_send(struct socket *sock, int id, const char *buf,\
|
|
|
|
|
const size_t length, unsigned long flags){
|
|
|
|
|
struct msghdr msg;
|
|
|
|
|
struct kvec vec;
|
|
|
|
|
int len, written = 0, left =length;
|
|
|
|
|
mm_segment_t oldmm;
|
|
|
|
|
int tcp_server_send(struct socket *ASocket, int AID, const char *ABuf,\
|
|
|
|
|
const size_t ALength, unsigned long AFlags){
|
|
|
|
|
struct msghdr LMsgHeader;
|
|
|
|
|
struct kvec LVec;
|
|
|
|
|
int LLen, LWritten, LLeft;
|
|
|
|
|
mm_segment_t LOldMM;
|
|
|
|
|
|
|
|
|
|
msg.msg_name = 0;
|
|
|
|
|
msg.msg_namelen = 0;
|
|
|
|
|
msg.msg_control = NULL;
|
|
|
|
|
msg.msg_controllen = 0;
|
|
|
|
|
msg.msg_flags = flags;
|
|
|
|
|
msg.msg_flags = 0;
|
|
|
|
|
LWritten = 0;
|
|
|
|
|
LLeft = ALength;
|
|
|
|
|
|
|
|
|
|
oldmm = get_fs(); set_fs(KERNEL_DS);
|
|
|
|
|
LMsgHeader.msg_name = 0;
|
|
|
|
|
LMsgHeader.msg_namelen = 0;
|
|
|
|
|
LMsgHeader.msg_control = NULL;
|
|
|
|
|
LMsgHeader.msg_controllen = 0;
|
|
|
|
|
LMsgHeader.msg_flags = AFlags;
|
|
|
|
|
LMsgHeader.msg_flags = 0;
|
|
|
|
|
|
|
|
|
|
LOldMM = get_fs(); set_fs(KERNEL_DS);
|
|
|
|
|
|
|
|
|
|
repeat_send:
|
|
|
|
|
vec.iov_len = left;
|
|
|
|
|
vec.iov_base = (char *)buf + written;
|
|
|
|
|
LVec.iov_len = LLeft;
|
|
|
|
|
LVec.iov_base = (char *)ABuf + LWritten;
|
|
|
|
|
|
|
|
|
|
len = kernel_sendmsg(sock, &msg, &vec, left, left);
|
|
|
|
|
LLen = kernel_sendmsg(ASocket, &LMsgHeader, &LVec, LLeft, LLeft);
|
|
|
|
|
|
|
|
|
|
if((len == -ERESTARTSYS) || (!(flags & MSG_DONTWAIT) &&\
|
|
|
|
|
(len == -EAGAIN)))
|
|
|
|
|
if((LLen == -ERESTARTSYS) || (!(AFlags & MSG_DONTWAIT) &&\
|
|
|
|
|
(LLen == -EAGAIN)))
|
|
|
|
|
goto repeat_send;
|
|
|
|
|
|
|
|
|
|
if(len > 0){
|
|
|
|
|
written += len;
|
|
|
|
|
left -= len;
|
|
|
|
|
if(left)
|
|
|
|
|
if(LLen > 0){
|
|
|
|
|
LWritten += LLen;
|
|
|
|
|
LLeft -= LLen;
|
|
|
|
|
if(LLeft)
|
|
|
|
|
goto repeat_send;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set_fs(oldmm);
|
|
|
|
|
return written?written:len;
|
|
|
|
|
set_fs(LOldMM);
|
|
|
|
|
return LWritten?LWritten:LLen;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int tcp_server_receive(struct socket *sock, int id,struct sockaddr_in *address,\
|
|
|
|
|
unsigned char *buf,int size, unsigned long flags){
|
|
|
|
|
struct msghdr msg;
|
|
|
|
|
struct kvec vec;
|
|
|
|
|
int len;
|
|
|
|
|
char *tmp = NULL;
|
|
|
|
|
int tcp_server_receive(struct socket *ASock, int AID,struct sockaddr_in *AAddress,\
|
|
|
|
|
unsigned char *ABuf,int ASize, unsigned long AFlags){
|
|
|
|
|
struct msghdr LMsgHeader;
|
|
|
|
|
struct kvec LVec;
|
|
|
|
|
int LLen;
|
|
|
|
|
char *LTmp = NULL;
|
|
|
|
|
|
|
|
|
|
if(sock==NULL){
|
|
|
|
|
if(ASock==NULL){
|
|
|
|
|
pr_info(" *** mtp | tcp server receive socket is NULL| "
|
|
|
|
|
" tcp_server_receive *** \n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
msg.msg_name = 0;
|
|
|
|
|
msg.msg_namelen = 0;
|
|
|
|
|
msg.msg_control = NULL;
|
|
|
|
|
msg.msg_controllen = 0;
|
|
|
|
|
msg.msg_flags = flags;
|
|
|
|
|
LMsgHeader.msg_name = 0;
|
|
|
|
|
LMsgHeader.msg_namelen = 0;
|
|
|
|
|
LMsgHeader.msg_control = NULL;
|
|
|
|
|
LMsgHeader.msg_controllen = 0;
|
|
|
|
|
LMsgHeader.msg_flags = AFlags;
|
|
|
|
|
|
|
|
|
|
vec.iov_len = size;
|
|
|
|
|
vec.iov_base = buf;
|
|
|
|
|
LVec.iov_len = ASize;
|
|
|
|
|
LVec.iov_base = ABuf;
|
|
|
|
|
|
|
|
|
|
read_again:
|
|
|
|
|
if(!skb_queue_empty(&sock->sk->sk_receive_queue))
|
|
|
|
|
if(!skb_queue_empty(&ASock->sk->sk_receive_queue))
|
|
|
|
|
pr_info("recv queue empty ? %s \n",
|
|
|
|
|
skb_queue_empty(&sock->sk->sk_receive_queue)?"yes":"no");
|
|
|
|
|
skb_queue_empty(&ASock->sk->sk_receive_queue)?"yes":"no");
|
|
|
|
|
|
|
|
|
|
len = kernel_recvmsg(sock, &msg, &vec, size, size, flags);
|
|
|
|
|
LLen = kernel_recvmsg(ASock, &LMsgHeader, &LVec, ASize, ASize, AFlags);
|
|
|
|
|
|
|
|
|
|
if(len == -EAGAIN || len == -ERESTARTSYS)
|
|
|
|
|
if(LLen == -EAGAIN || LLen == -ERESTARTSYS)
|
|
|
|
|
goto read_again;
|
|
|
|
|
|
|
|
|
|
tmp = inet_ntoa(&(address->sin_addr));
|
|
|
|
|
LTmp = inet_ntoa(&(AAddress->sin_addr));
|
|
|
|
|
|
|
|
|
|
pr_info("client-> %s:%d, says: %s\n", tmp, ntohs(address->sin_port), buf);
|
|
|
|
|
pr_info("client-> %s:%d, says: %s\n", LTmp, ntohs(AAddress->sin_port), ABuf);
|
|
|
|
|
|
|
|
|
|
kfree(tmp);
|
|
|
|
|
//len = msg.msg_iter.kvec->iov_len;
|
|
|
|
|
return len;
|
|
|
|
|
kfree(LTmp);
|
|
|
|
|
return LLen;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int connection_handler(void *data){
|
|
|
|
|
struct tcp_conn_handler_data *conn_data =
|
|
|
|
|
(struct tcp_conn_handler_data *)data;
|
|
|
|
|
int connection_handler(void *AData){
|
|
|
|
|
struct tcp_conn_handler_data *LConnData =
|
|
|
|
|
(struct tcp_conn_handler_data *)AData;
|
|
|
|
|
|
|
|
|
|
struct sockaddr_in *address = conn_data->address;
|
|
|
|
|
struct socket *accept_socket = conn_data->accept_socket;
|
|
|
|
|
int id = conn_data->thread_id;
|
|
|
|
|
struct sockaddr_in *LAddress = LConnData->FAddress;
|
|
|
|
|
struct socket *LAcceptSocket = LConnData->FAcceptSocket;
|
|
|
|
|
int LID = LConnData->FThreadID;
|
|
|
|
|
|
|
|
|
|
int ret;
|
|
|
|
|
int len = 49;
|
|
|
|
|
unsigned char in_buf[len+1];
|
|
|
|
|
unsigned char out_buf[len+1];
|
|
|
|
|
int LRet;
|
|
|
|
|
int LLen = 49;
|
|
|
|
|
unsigned char LInBuf[LLen+1];
|
|
|
|
|
unsigned char LOutBuf[LLen+1];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DECLARE_WAITQUEUE(recv_wait, current);
|
|
|
|
|
allow_signal(SIGKILL|SIGSTOP);
|
|
|
|
|
|
|
|
|
|
while(1){
|
|
|
|
|
add_wait_queue(&accept_socket->sk->sk_wq->wait, &recv_wait);
|
|
|
|
|
add_wait_queue(&LAcceptSocket->sk->sk_wq->wait, &recv_wait);
|
|
|
|
|
|
|
|
|
|
while(skb_queue_empty(&accept_socket->sk->sk_receive_queue)){
|
|
|
|
|
while(skb_queue_empty(&LAcceptSocket->sk->sk_receive_queue)){
|
|
|
|
|
__set_current_state(TASK_INTERRUPTIBLE);
|
|
|
|
|
schedule_timeout(HZ);
|
|
|
|
|
|
|
|
|
@ -192,203 +194,187 @@ int connection_handler(void *data){
|
|
|
|
|
"thread stopped | connection_handler *** \n");
|
|
|
|
|
|
|
|
|
|
//tcp_conn_handler->thread[id] = NULL;
|
|
|
|
|
tcp_conn_handler->tcp_conn_handler_stopped[id]= 1;
|
|
|
|
|
STCPConnHandler->tcp_conn_handler_stopped[LID]= 1;
|
|
|
|
|
|
|
|
|
|
__set_current_state(TASK_RUNNING);
|
|
|
|
|
remove_wait_queue(&accept_socket->sk->sk_wq->wait,\
|
|
|
|
|
remove_wait_queue(&LAcceptSocket->sk->sk_wq->wait,\
|
|
|
|
|
&recv_wait);
|
|
|
|
|
kfree(tcp_conn_handler->data[id]->address);
|
|
|
|
|
kfree(tcp_conn_handler->data[id]);
|
|
|
|
|
sock_release(tcp_conn_handler->data[id]->accept_socket);
|
|
|
|
|
kfree(STCPConnHandler->data[LID]->FAddress);
|
|
|
|
|
kfree(STCPConnHandler->data[LID]);
|
|
|
|
|
sock_release(STCPConnHandler->data[LID]->FAcceptSocket);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(signal_pending(current)){
|
|
|
|
|
__set_current_state(TASK_RUNNING);
|
|
|
|
|
remove_wait_queue(&accept_socket->sk->sk_wq->wait,\
|
|
|
|
|
remove_wait_queue(&LAcceptSocket->sk->sk_wq->wait,\
|
|
|
|
|
&recv_wait);
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
__set_current_state(TASK_RUNNING);
|
|
|
|
|
remove_wait_queue(&accept_socket->sk->sk_wq->wait, &recv_wait);
|
|
|
|
|
remove_wait_queue(&LAcceptSocket->sk->sk_wq->wait, &recv_wait);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pr_info("receiving message\n");
|
|
|
|
|
memset(in_buf, 0, len+1);
|
|
|
|
|
ret = tcp_server_receive(accept_socket, id, address, in_buf, len,\
|
|
|
|
|
memset(LInBuf, 0, LLen+1);
|
|
|
|
|
LRet = tcp_server_receive(LAcceptSocket, LID, LAddress, LInBuf, LLen,\
|
|
|
|
|
MSG_DONTWAIT);
|
|
|
|
|
if(ret > 0){
|
|
|
|
|
if(memcmp(in_buf, "HOLA", 4) == 0){
|
|
|
|
|
memset(out_buf, 0, len+1);
|
|
|
|
|
strcat(out_buf, "HOLASI");
|
|
|
|
|
pr_info("sending response: %s\n", out_buf);
|
|
|
|
|
tcp_server_send(accept_socket, id, out_buf,\
|
|
|
|
|
strlen(out_buf), MSG_DONTWAIT);
|
|
|
|
|
if(LRet > 0){
|
|
|
|
|
if(memcmp(LInBuf, "HOLA", 4) == 0){
|
|
|
|
|
memset(LOutBuf, 0, LLen+1);
|
|
|
|
|
strcat(LOutBuf, "HOLASI");
|
|
|
|
|
pr_info("sending response: %s\n", LOutBuf);
|
|
|
|
|
tcp_server_send(LAcceptSocket, LID, LOutBuf,\
|
|
|
|
|
strlen(LOutBuf), MSG_DONTWAIT);
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
tmp = inet_ntoa(&(address->sin_addr));
|
|
|
|
|
pr_info("connection handler: %d of: %s %d done sending "
|
|
|
|
|
" HOLASI\n", id, tmp, ntohs(address->sin_port));
|
|
|
|
|
kfree(tmp);
|
|
|
|
|
*/
|
|
|
|
|
if(memcmp(in_buf, "ADIOS", 5) == 0){
|
|
|
|
|
memset(out_buf, 0, len+1);
|
|
|
|
|
strcat(out_buf, "ADIOSAMIGO");
|
|
|
|
|
pr_info("sending response: %s\n", out_buf);
|
|
|
|
|
tcp_server_send(accept_socket, id, out_buf,\
|
|
|
|
|
strlen(out_buf), MSG_DONTWAIT);
|
|
|
|
|
if(memcmp(LInBuf, "ADIOS", 5) == 0){
|
|
|
|
|
memset(LOutBuf, 0, LLen+1);
|
|
|
|
|
strcat(LOutBuf, "ADIOSAMIGO");
|
|
|
|
|
pr_info("sending response: %s\n", LOutBuf);
|
|
|
|
|
tcp_server_send(LAcceptSocket, LID, LOutBuf,\
|
|
|
|
|
strlen(LOutBuf), MSG_DONTWAIT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out:
|
|
|
|
|
/*
|
|
|
|
|
tmp = inet_ntoa(&(address->sin_addr));
|
|
|
|
|
|
|
|
|
|
pr_info("connection handler: %d of: %s %d exiting normally\n",
|
|
|
|
|
id, tmp, ntohs(address->sin_port));
|
|
|
|
|
kfree(tmp);
|
|
|
|
|
*/
|
|
|
|
|
tcp_conn_handler->tcp_conn_handler_stopped[id]= 1;
|
|
|
|
|
kfree(tcp_conn_handler->data[id]->address);
|
|
|
|
|
kfree(tcp_conn_handler->data[id]);
|
|
|
|
|
sock_release(tcp_conn_handler->data[id]->accept_socket);
|
|
|
|
|
//spin_lock(&tcp_server_lock);
|
|
|
|
|
tcp_conn_handler->thread[id] = NULL;
|
|
|
|
|
//spin_unlock(&tcp_server_lock);
|
|
|
|
|
//return 0;
|
|
|
|
|
STCPConnHandler->tcp_conn_handler_stopped[LID]= 1;
|
|
|
|
|
kfree(STCPConnHandler->data[LID]->FAddress);
|
|
|
|
|
kfree(STCPConnHandler->data[LID]);
|
|
|
|
|
sock_release(STCPConnHandler->data[LID]->FAcceptSocket);
|
|
|
|
|
STCPConnHandler->thread[LID] = NULL;
|
|
|
|
|
do_exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int tcp_server_accept(void){
|
|
|
|
|
int accept_err = 0;
|
|
|
|
|
struct socket *socket;
|
|
|
|
|
struct socket *accept_socket = NULL;
|
|
|
|
|
struct inet_connection_sock *isock;
|
|
|
|
|
int id = 0;
|
|
|
|
|
int LAcceptErr = 0;
|
|
|
|
|
struct socket *LSocket;
|
|
|
|
|
struct socket *LAcceptSocket = NULL;
|
|
|
|
|
struct inet_connection_sock *LISock;
|
|
|
|
|
int LID = 0;
|
|
|
|
|
DECLARE_WAITQUEUE(accept_wait, current);
|
|
|
|
|
allow_signal(SIGKILL|SIGSTOP);
|
|
|
|
|
socket = tcp_server->listen_socket;
|
|
|
|
|
LSocket = FTCPServer_Service->FListenSocket;
|
|
|
|
|
pr_info(" *** mtp | creating the accept socket | tcp_server_accept "
|
|
|
|
|
"*** \n");
|
|
|
|
|
|
|
|
|
|
while(1){
|
|
|
|
|
struct tcp_conn_handler_data *data = NULL;
|
|
|
|
|
struct sockaddr_in *client = NULL;
|
|
|
|
|
char *tmp;
|
|
|
|
|
struct tcp_conn_handler_data *LTCPConnHData = NULL;
|
|
|
|
|
struct sockaddr_in *LClient = NULL;
|
|
|
|
|
char *LTmp;
|
|
|
|
|
int addr_len;
|
|
|
|
|
|
|
|
|
|
accept_err =
|
|
|
|
|
sock_create(socket->sk->sk_family, socket->type,\
|
|
|
|
|
socket->sk->sk_protocol, &accept_socket);
|
|
|
|
|
LAcceptErr =
|
|
|
|
|
sock_create(LSocket->sk->sk_family, LSocket->type,\
|
|
|
|
|
LSocket->sk->sk_protocol, &LAcceptSocket);
|
|
|
|
|
|
|
|
|
|
if(accept_err < 0 || !accept_socket){
|
|
|
|
|
if(LAcceptErr < 0 || !LAcceptSocket){
|
|
|
|
|
pr_info(" *** mtp | accept_error: %d while creating "
|
|
|
|
|
"tcp server accept socket | "
|
|
|
|
|
"tcp_server_accept *** \n", accept_err);
|
|
|
|
|
"tcp_server_accept *** \n", LAcceptErr);
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
accept_socket->type = socket->type;
|
|
|
|
|
accept_socket->ops = socket->ops;
|
|
|
|
|
LAcceptSocket->type = LSocket->type;
|
|
|
|
|
LAcceptSocket->ops = LSocket->ops;
|
|
|
|
|
|
|
|
|
|
isock = inet_csk(socket->sk);
|
|
|
|
|
LISock = inet_csk(LSocket->sk);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
add_wait_queue(&socket->sk->sk_wq->wait, &accept_wait);
|
|
|
|
|
while(reqsk_queue_empty(&isock->icsk_accept_queue)){
|
|
|
|
|
add_wait_queue(&LSocket->sk->sk_wq->wait, &accept_wait);
|
|
|
|
|
while(reqsk_queue_empty(&LISock->icsk_accept_queue)){
|
|
|
|
|
__set_current_state(TASK_INTERRUPTIBLE);
|
|
|
|
|
schedule_timeout(HZ);
|
|
|
|
|
if(kthread_should_stop()){
|
|
|
|
|
pr_info(" *** mtp | tcp server acceptor thread "
|
|
|
|
|
"stopped | tcp_server_accept *** \n");
|
|
|
|
|
tcp_acceptor_stopped = 1;
|
|
|
|
|
STCPAcceptorStopped = 1;
|
|
|
|
|
__set_current_state(TASK_RUNNING);
|
|
|
|
|
remove_wait_queue(&socket->sk->sk_wq->wait,\
|
|
|
|
|
remove_wait_queue(&LSocket->sk->sk_wq->wait,\
|
|
|
|
|
&accept_wait);
|
|
|
|
|
sock_release(accept_socket);
|
|
|
|
|
sock_release(LAcceptSocket);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(signal_pending(current)){
|
|
|
|
|
__set_current_state(TASK_RUNNING);
|
|
|
|
|
remove_wait_queue(&socket->sk->sk_wq->wait,\
|
|
|
|
|
remove_wait_queue(&LSocket->sk->sk_wq->wait,\
|
|
|
|
|
&accept_wait);
|
|
|
|
|
goto release;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
__set_current_state(TASK_RUNNING);
|
|
|
|
|
remove_wait_queue(&socket->sk->sk_wq->wait, &accept_wait);
|
|
|
|
|
remove_wait_queue(&LSocket->sk->sk_wq->wait, &accept_wait);
|
|
|
|
|
|
|
|
|
|
pr_info("accept connection\n");
|
|
|
|
|
|
|
|
|
|
accept_err =
|
|
|
|
|
socket->ops->accept(socket, accept_socket, O_NONBLOCK);
|
|
|
|
|
LAcceptErr =
|
|
|
|
|
LSocket->ops->accept(LSocket, LAcceptSocket, O_NONBLOCK);
|
|
|
|
|
|
|
|
|
|
if(accept_err < 0){
|
|
|
|
|
if(LAcceptErr < 0){
|
|
|
|
|
pr_info(" *** mtp | accept_error: %d while accepting "
|
|
|
|
|
"tcp server | tcp_server_accept *** \n",
|
|
|
|
|
accept_err);
|
|
|
|
|
LAcceptErr);
|
|
|
|
|
goto release;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client = kmalloc(sizeof(struct sockaddr_in), GFP_KERNEL);
|
|
|
|
|
memset(client, 0, sizeof(struct sockaddr_in));
|
|
|
|
|
LClient = kmalloc(sizeof(struct sockaddr_in), GFP_KERNEL);
|
|
|
|
|
memset(LClient, 0, sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
|
|
addr_len = sizeof(struct sockaddr_in);
|
|
|
|
|
|
|
|
|
|
accept_err =
|
|
|
|
|
accept_socket->ops->getname(accept_socket,\
|
|
|
|
|
(struct sockaddr *)client,\
|
|
|
|
|
LAcceptErr =
|
|
|
|
|
LAcceptSocket->ops->getname(LAcceptSocket,\
|
|
|
|
|
(struct sockaddr *)LClient,\
|
|
|
|
|
&addr_len, 2);
|
|
|
|
|
|
|
|
|
|
if(accept_err < 0){
|
|
|
|
|
if(LAcceptErr < 0){
|
|
|
|
|
pr_info(" *** mtp | accept_error: %d in getname "
|
|
|
|
|
"tcp server | tcp_server_accept *** \n",
|
|
|
|
|
accept_err);
|
|
|
|
|
LAcceptErr);
|
|
|
|
|
goto release;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tmp = inet_ntoa(&(client->sin_addr));
|
|
|
|
|
LTmp = inet_ntoa(&(LClient->sin_addr));
|
|
|
|
|
|
|
|
|
|
pr_info("connection from: %s %d \n",
|
|
|
|
|
tmp, ntohs(client->sin_port));
|
|
|
|
|
LTmp, ntohs(LClient->sin_port));
|
|
|
|
|
|
|
|
|
|
kfree(tmp);
|
|
|
|
|
kfree(LTmp);
|
|
|
|
|
|
|
|
|
|
pr_info("handle connection\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(id = 0; id < MAX_CONNS; id++){
|
|
|
|
|
if(tcp_conn_handler->thread[id] == NULL)
|
|
|
|
|
for(LID = 0; LID < MAX_CONNS; LID++){
|
|
|
|
|
if(STCPConnHandler->thread[LID] == NULL)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pr_info("gave free id: %d\n", id);
|
|
|
|
|
pr_info("gave free id: %d\n", LID);
|
|
|
|
|
|
|
|
|
|
if(id == MAX_CONNS)
|
|
|
|
|
if(LID == MAX_CONNS)
|
|
|
|
|
goto release;
|
|
|
|
|
|
|
|
|
|
data = kmalloc(sizeof(struct tcp_conn_handler_data), GFP_KERNEL);
|
|
|
|
|
memset(data, 0, sizeof(struct tcp_conn_handler_data));
|
|
|
|
|
LTCPConnHData = kmalloc(sizeof(struct tcp_conn_handler_data), GFP_KERNEL);
|
|
|
|
|
memset(LTCPConnHData, 0, sizeof(struct tcp_conn_handler_data));
|
|
|
|
|
|
|
|
|
|
data->address = client;
|
|
|
|
|
data->accept_socket = accept_socket;
|
|
|
|
|
data->thread_id = id;
|
|
|
|
|
LTCPConnHData->FAddress = LClient;
|
|
|
|
|
LTCPConnHData->FAcceptSocket = LAcceptSocket;
|
|
|
|
|
LTCPConnHData->FThreadID = LID;
|
|
|
|
|
|
|
|
|
|
tcp_conn_handler->tcp_conn_handler_stopped[id] = 0;
|
|
|
|
|
tcp_conn_handler->data[id] = data;
|
|
|
|
|
tcp_conn_handler->thread[id] =
|
|
|
|
|
kthread_run((void *)connection_handler, (void *)data, MODULE_NAME);
|
|
|
|
|
STCPConnHandler->tcp_conn_handler_stopped[LID] = 0;
|
|
|
|
|
STCPConnHandler->data[LID] = LTCPConnHData;
|
|
|
|
|
STCPConnHandler->thread[LID] =
|
|
|
|
|
kthread_run((void *)connection_handler, (void *)LTCPConnHData, MODULE_NAME);
|
|
|
|
|
|
|
|
|
|
if(kthread_should_stop()){
|
|
|
|
|
pr_info(" *** mtp | tcp server acceptor thread stopped"
|
|
|
|
|
" | tcp_server_accept *** \n");
|
|
|
|
|
tcp_acceptor_stopped = 1;
|
|
|
|
|
STCPAcceptorStopped = 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -399,60 +385,60 @@ int tcp_server_accept(void){
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tcp_acceptor_stopped = 1;
|
|
|
|
|
STCPAcceptorStopped = 1;
|
|
|
|
|
do_exit(0);
|
|
|
|
|
release:
|
|
|
|
|
sock_release(accept_socket);
|
|
|
|
|
sock_release(LAcceptSocket);
|
|
|
|
|
err:
|
|
|
|
|
tcp_acceptor_stopped = 1;
|
|
|
|
|
STCPAcceptorStopped = 1;
|
|
|
|
|
do_exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int tcp_server_listen(void)
|
|
|
|
|
{
|
|
|
|
|
int server_err;
|
|
|
|
|
struct socket *conn_socket;
|
|
|
|
|
struct sockaddr_in server;
|
|
|
|
|
int LServerErr;
|
|
|
|
|
struct socket *LConnSocket;
|
|
|
|
|
struct sockaddr_in LServer;
|
|
|
|
|
|
|
|
|
|
DECLARE_WAIT_QUEUE_HEAD(wq);
|
|
|
|
|
|
|
|
|
|
allow_signal(SIGKILL|SIGTERM);
|
|
|
|
|
|
|
|
|
|
server_err = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP,\
|
|
|
|
|
&tcp_server->listen_socket);
|
|
|
|
|
if(server_err < 0){
|
|
|
|
|
LServerErr = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP,\
|
|
|
|
|
&FTCPServer_Service->FListenSocket);
|
|
|
|
|
if(LServerErr < 0){
|
|
|
|
|
pr_info(" *** mtp | Error: %d while creating tcp server "
|
|
|
|
|
"listen socket | tcp_server_listen *** \n", server_err);
|
|
|
|
|
"listen socket | tcp_server_listen *** \n", LServerErr);
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
conn_socket = tcp_server->listen_socket;
|
|
|
|
|
tcp_server->listen_socket->sk->sk_reuse = 1;
|
|
|
|
|
LConnSocket = FTCPServer_Service->FListenSocket;
|
|
|
|
|
FTCPServer_Service->FListenSocket->sk->sk_reuse = 1;
|
|
|
|
|
|
|
|
|
|
server.sin_addr.s_addr = INADDR_ANY;
|
|
|
|
|
server.sin_family = AF_INET;
|
|
|
|
|
server.sin_port = htons(DEFAULT_PORT);
|
|
|
|
|
LServer.sin_addr.s_addr = INADDR_ANY;
|
|
|
|
|
LServer.sin_family = AF_INET;
|
|
|
|
|
LServer.sin_port = htons(DEFAULT_PORT);
|
|
|
|
|
|
|
|
|
|
server_err =
|
|
|
|
|
conn_socket->ops->bind(conn_socket, (struct sockaddr*)&server,\
|
|
|
|
|
sizeof(server));
|
|
|
|
|
LServerErr =
|
|
|
|
|
LConnSocket->ops->bind(LConnSocket, (struct sockaddr*)&LServer,\
|
|
|
|
|
sizeof(LServer));
|
|
|
|
|
|
|
|
|
|
if(server_err < 0){
|
|
|
|
|
if(LServerErr < 0){
|
|
|
|
|
pr_info(" *** mtp | Error: %d while binding tcp server "
|
|
|
|
|
"listen socket | tcp_server_listen *** \n", server_err);
|
|
|
|
|
"listen socket | tcp_server_listen *** \n", LServerErr);
|
|
|
|
|
goto release;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
server_err = conn_socket->ops->listen(conn_socket, 16);
|
|
|
|
|
LServerErr = LConnSocket->ops->listen(LConnSocket, 16);
|
|
|
|
|
|
|
|
|
|
if(server_err < 0){
|
|
|
|
|
if(LServerErr < 0){
|
|
|
|
|
pr_info(" *** mtp | Error: %d while listening in tcp "
|
|
|
|
|
"server listen socket | tcp_server_listen "
|
|
|
|
|
"*** \n", server_err);
|
|
|
|
|
"*** \n", LServerErr);
|
|
|
|
|
goto release;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tcp_server->accept_thread =
|
|
|
|
|
FTCPServer_Service->FAccpeptThread =
|
|
|
|
|
kthread_run((void*)tcp_server_accept, NULL, MODULE_NAME);
|
|
|
|
|
|
|
|
|
|
while(1){
|
|
|
|
@ -469,19 +455,19 @@ int tcp_server_listen(void)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sock_release(conn_socket);
|
|
|
|
|
tcp_listener_stopped = 1;
|
|
|
|
|
sock_release(LConnSocket);
|
|
|
|
|
STCPListenerStopped = 1;
|
|
|
|
|
do_exit(0);
|
|
|
|
|
release:
|
|
|
|
|
sock_release(conn_socket);
|
|
|
|
|
sock_release(LConnSocket);
|
|
|
|
|
err:
|
|
|
|
|
tcp_listener_stopped = 1;
|
|
|
|
|
STCPListenerStopped = 1;
|
|
|
|
|
do_exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int tcp_server_start(void){
|
|
|
|
|
tcp_server->running = 1;
|
|
|
|
|
tcp_server->thread = kthread_run((void *)tcp_server_listen, NULL,\
|
|
|
|
|
FTCPServer_Service->FRunning = 1;
|
|
|
|
|
FTCPServer_Service->FThread = kthread_run((void *)tcp_server_listen, NULL,\
|
|
|
|
|
MODULE_NAME);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -489,11 +475,11 @@ int tcp_server_start(void){
|
|
|
|
|
int network_server_init(void){
|
|
|
|
|
pr_info(" *** mtp | network_server initiated | "
|
|
|
|
|
"network_server_init ***\n");
|
|
|
|
|
tcp_server = kmalloc(sizeof(struct tcp_server_service), GFP_KERNEL);
|
|
|
|
|
memset(tcp_server, 0, sizeof(struct tcp_server_service));
|
|
|
|
|
FTCPServer_Service = kmalloc(sizeof(struct tcp_server_service), GFP_KERNEL);
|
|
|
|
|
memset(FTCPServer_Service, 0, sizeof(struct tcp_server_service));
|
|
|
|
|
|
|
|
|
|
tcp_conn_handler = kmalloc(sizeof(struct tcp_conn_handler), GFP_KERNEL);
|
|
|
|
|
memset(tcp_conn_handler, 0, sizeof(struct tcp_conn_handler));
|
|
|
|
|
STCPConnHandler = kmalloc(sizeof(struct tcp_conn_handler), GFP_KERNEL);
|
|
|
|
|
memset(STCPConnHandler, 0, sizeof(struct tcp_conn_handler));
|
|
|
|
|
|
|
|
|
|
tcp_server_start();
|
|
|
|
|
return 0;
|
|
|
|
@ -503,20 +489,20 @@ void network_server_exit(void){
|
|
|
|
|
int ret;
|
|
|
|
|
int id;
|
|
|
|
|
|
|
|
|
|
if(tcp_server->thread == NULL)
|
|
|
|
|
if(FTCPServer_Service->FThread == NULL)
|
|
|
|
|
pr_info(" *** mtp | No kernel thread to kill | "
|
|
|
|
|
"network_server_exit *** \n");
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for(id = 0; id < MAX_CONNS; id++)
|
|
|
|
|
{
|
|
|
|
|
if(tcp_conn_handler->thread[id] != NULL)
|
|
|
|
|
if(STCPConnHandler->thread[id] != NULL)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if(!tcp_conn_handler->tcp_conn_handler_stopped[id])
|
|
|
|
|
if(!STCPConnHandler->tcp_conn_handler_stopped[id])
|
|
|
|
|
{
|
|
|
|
|
ret =
|
|
|
|
|
kthread_stop(tcp_conn_handler->thread[id]);
|
|
|
|
|
kthread_stop(STCPConnHandler->thread[id]);
|
|
|
|
|
|
|
|
|
|
if(!ret)
|
|
|
|
|
pr_info(" *** mtp | tcp server "
|
|
|
|
@ -527,32 +513,32 @@ void network_server_exit(void){
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!tcp_acceptor_stopped)
|
|
|
|
|
if(!STCPAcceptorStopped)
|
|
|
|
|
{
|
|
|
|
|
ret = kthread_stop(tcp_server->accept_thread);
|
|
|
|
|
ret = kthread_stop(FTCPServer_Service->FAccpeptThread);
|
|
|
|
|
if(!ret)
|
|
|
|
|
pr_info(" *** mtp | tcp server acceptor thread"
|
|
|
|
|
" stopped | network_server_exit *** \n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!tcp_listener_stopped)
|
|
|
|
|
if(!STCPListenerStopped)
|
|
|
|
|
{
|
|
|
|
|
ret = kthread_stop(tcp_server->thread);
|
|
|
|
|
ret = kthread_stop(FTCPServer_Service->FThread);
|
|
|
|
|
if(!ret)
|
|
|
|
|
pr_info(" *** mtp | tcp server listening thread"
|
|
|
|
|
" stopped | network_server_exit *** \n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(tcp_server->listen_socket != NULL && !tcp_listener_stopped)
|
|
|
|
|
if(FTCPServer_Service->FListenSocket != NULL && !STCPListenerStopped)
|
|
|
|
|
{
|
|
|
|
|
sock_release(tcp_server->listen_socket);
|
|
|
|
|
tcp_server->listen_socket = NULL;
|
|
|
|
|
sock_release(FTCPServer_Service->FListenSocket);
|
|
|
|
|
FTCPServer_Service->FListenSocket = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
kfree(tcp_conn_handler);
|
|
|
|
|
kfree(tcp_server);
|
|
|
|
|
tcp_server = NULL;
|
|
|
|
|
kfree(STCPConnHandler);
|
|
|
|
|
kfree(FTCPServer_Service);
|
|
|
|
|
FTCPServer_Service = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|