occlum/demos/local_attestation/AppResponder/responder.c
2020-06-04 20:05:55 +08:00

171 lines
5.0 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/un.h>
#include <sys/select.h>
#include <sys/time.h>
#include "fifo_def.h"
#include "proc_msg.h"
#define BACKLOG 5
#define CONCURRENT_MAX 32
#define SERVER_PORT 8888
#define BUFFER_SIZE 1024
int m_server_sock_fd;
int m_shutdown;
int server_init() {
struct sockaddr_in srv_addr;
memset(&srv_addr, 0, sizeof(srv_addr));
srv_addr.sin_family = AF_INET;
srv_addr.sin_addr.s_addr = INADDR_ANY;
srv_addr.sin_port = htons(SERVER_PORT);
m_server_sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);;
if (m_server_sock_fd == -1) {
printf("socket initiazation error: %d\n", errno);
return -1;
}
int bind_result = bind(m_server_sock_fd, (struct sockaddr *)&srv_addr, sizeof(srv_addr));
if (bind_result == -1) {
printf("bind error: %d\n", errno);
close(m_server_sock_fd);
return -1;
}
if (listen(m_server_sock_fd, BACKLOG) == -1) {
printf("listen error: %d\n", errno);
close(m_server_sock_fd);
return -1;
}
m_shutdown = 0;
return 0;
}
int work() {
int client_fds[CONCURRENT_MAX] = {0};
fd_set server_fd_set;
int max_fd = -1;
struct timeval tv;
char input_msg[BUFFER_SIZE];
char recv_msg[BUFFER_SIZE];
int ret;
while (!m_shutdown) {
// set 10s timeout for select()
tv.tv_sec = 10;
tv.tv_usec = 0;
FD_ZERO(&server_fd_set);
// listening on server socket
FD_SET(m_server_sock_fd, &server_fd_set);
if (max_fd < m_server_sock_fd) {
max_fd = m_server_sock_fd;
}
// listening on all client connections
for (int i = 0; i < CONCURRENT_MAX; i++) {
if (client_fds[i] != 0) {
FD_SET(client_fds[i], &server_fd_set);
if (max_fd < client_fds[i]) {
max_fd = client_fds[i];
}
}
}
ret = select(max_fd + 1, &server_fd_set, NULL, NULL, &tv);
if (ret < 0) {
printf("Warning: server would shutdown\n");
continue;
} else if (ret == 0) {
// timeout
continue;
}
if (FD_ISSET(m_server_sock_fd, &server_fd_set)) {
// if there is new connection request
struct sockaddr_in clt_addr;
socklen_t len = sizeof(clt_addr);
// accept this connection request
int client_sock_fd = accept(m_server_sock_fd, (struct sockaddr *)&clt_addr, &len);
if (client_sock_fd > 0) {
// add new connection to connection pool if it's not full
int index = -1;
for (int i = 0; i < CONCURRENT_MAX; i++) {
if (client_fds[i] == 0) {
index = i;
client_fds[i] = client_sock_fd;
break;
}
}
if (index < 0) {
printf("server reach maximum connection!\n");
bzero(input_msg, BUFFER_SIZE);
strcpy(input_msg, "server reach maximum connection\n");
send(client_sock_fd, input_msg, BUFFER_SIZE, 0);
}
} else if (client_sock_fd < 0) {
printf("server: accept() return failure, %s, would exit.\n", strerror(errno));
close(m_server_sock_fd);
break;
}
}
for (int i = 0; i < CONCURRENT_MAX; i++) {
if ((client_fds[i] != 0)
&& (FD_ISSET(client_fds[i], &server_fd_set))) {
// there is request messages from client connectsions
FIFO_MSG *msg;
bzero(recv_msg, BUFFER_SIZE);
long byte_num = recv(client_fds[i], recv_msg, BUFFER_SIZE, 0);
if (byte_num > 0) {
if (byte_num > BUFFER_SIZE) {
byte_num = BUFFER_SIZE;
}
recv_msg[byte_num] = '\0';
msg = (FIFO_MSG *)malloc(byte_num);
if (!msg) {
printf("memory allocation failure\n");
continue;
}
memset(msg, 0, byte_num);
memcpy(msg, recv_msg, byte_num);
msg->header.sockfd = client_fds[i];
proc(msg);
} else if (byte_num < 0) {
printf("failed to receive message.\n");
} else {
// client connect is closed
FD_CLR(client_fds[i], &server_fd_set);
close(client_fds[i]);
client_fds[i] = 0;
}
}
}
}
}
int main() {
int rc;
rc = server_init();
if (rc != 0) {
printf("server init failure\n");
return rc;
}
return work();
}