/* ** Copyright (C) 2020 Johannes Kepler University Linz, Institute of Networks and Security ** Copyright (C) 2020 CDL Digidow ** ** Licensed under the EUPL, Version 1.2 or – as soon they will be approved by ** the European Commission - subsequent versions of the EUPL (the "Licence"). ** You may not use this work except in compliance with the Licence. ** ** You should have received a copy of the European Union Public License along ** with this program. If not, you may obtain a copy of the Licence at: ** ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the Licence is distributed on an "AS IS" basis, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the Licence for the specific language governing permissions and ** limitations under the Licence. ** */ #include "server.h" int server_open(int16_t port) { struct sockaddr_in servaddr; int connfd = 0; connfd = socket(AF_INET, SOCK_STREAM, 0); if (-1 == connfd) { printf("server_open: failed to create endpoint.\n"); return -1; } servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(port); if (0 != bind(connfd, (const struct sockaddr *) &servaddr, sizeof(servaddr))) { printf("server_open: failed to bind socket\n"); close(connfd); return -1; } return connfd; } int server_start(conn_handler handler, int16_t port) { struct sockaddr_in client; unsigned int client_len = 0; int connfd = 0; int clientfd = 0; int len = 0; int ret = 0; //<0 .. failure, 0 .. continue, 1 .. exit, 2 .. shutdown char buffer[MAX_BUFSIZE]; if(NULL == handler) { printf("server_start: received empty handler, stopping\n"); return -1; } connfd = server_open(port); if(-1 == connfd) { printf("server_start: could not open port, stopping\n"); return -1; } if (0 != listen(connfd, MAX_CLIENTS)) { printf("server_start: listen failed, stopping\n"); return -1; } printf("server_start: listening\n"); for(ret = 1; 1 == ret;) { client_len = sizeof(client); clientfd = accept(connfd, (struct sockaddr *) &client, &client_len); if (0 >= clientfd) { printf("server_start: connection to client failed\n"); ret = -1; } else { for(ret = 0; 0 == ret;) { bzero(buffer, MAX_BUFSIZE); len = 0; do { ret = read(clientfd, &buffer[len], sizeof(buffer)-len); len += ret; } while(0 < ret && buffer[len-1] != '\n'); if (0 > ret) { printf("server_start: cannot read from socket\n"); ret = -1; } else if(0 == ret) { printf("server_start: client closed connection\n"); ret = 1; } else { ret = handler(buffer); } if (0 == ret && 0 >= write(clientfd, buffer, strlen(buffer))) { printf("server_start: cannot write to socket\n"); ret = 1; } } if (0 != close(clientfd)) { printf("server_start: failed to close client connection properly\n"); ret = -1; } } } printf("server_start: closing connection\n"); if (0 != close(connfd)) { printf("server_start: failed to close server port properly\n"); ret = -1; } return ret; }