From 63519d6ae4cb20ae4871310e09a28fd59f5c9fc7 Mon Sep 17 00:00:00 2001 From: Johann Latocha Date: Tue, 31 Jan 2012 23:52:24 +0100 Subject: [ALL] Some refactoring --- src/server/net.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/server/net.c (limited to 'src/server/net.c') diff --git a/src/server/net.c b/src/server/net.c new file mode 100644 index 0000000..87af60f --- /dev/null +++ b/src/server/net.c @@ -0,0 +1,133 @@ +/* + * This file is part of the Distributed Network Block Device 3 + * + * Copyright(c) 2011-2012 Johann Latocha + * + * This file may be licensed under the terms of of the + * GNU General Public License Version 2 (the ``GPL''). + * + * Software distributed under the License is distributed + * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the GPL for the specific language + * governing rights and limitations. + * + * You should have received a copy of the GPL along with this + * program. If not, go to http://www.gnu.org/licenses/gpl.html + * or write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "server.h" +#include "hashtable.h" + +void *dnbd3_handle_query(void *client_socket) +{ + int image_file = -1; + off_t filesize = 0; + int sock = (int) (uintptr_t) client_socket; + dnbd3_request_t request; + dnbd3_reply_t reply; + uint16_t cmd; + + while (recv(sock, &request, sizeof(dnbd3_request_t), MSG_WAITALL) > 0) + { + cmd = request.cmd; + switch (cmd) + { + case CMD_PING: + reply.cmd = request.cmd; + memcpy(reply.handle, request.handle, sizeof(request.handle)); + send(sock, (char *) &reply, sizeof(dnbd3_reply_t), 0); + break; + + case CMD_GET_SIZE: + pthread_spin_lock(&_spinlock); // because of reloading config + image_file = open(dnbd3_ht_search(request.image_id), O_RDONLY); + pthread_spin_unlock(&_spinlock); + if (image_file < 0) + { + printf("ERROR: Client requested an unknown image id.\n"); + filesize = 0; + } + else + { + struct stat st; + fstat(image_file, &st); + filesize = st.st_size; + } + reply.cmd = request.cmd; + reply.filesize = filesize; + send(sock, (char *) &reply, sizeof(dnbd3_reply_t), 0); + break; + + case CMD_GET_BLOCK: + if (image_file < 0) + break; + + reply.cmd = request.cmd; + memcpy(reply.handle, request.handle, sizeof(request.handle)); + send(sock, (char *) &reply, sizeof(dnbd3_reply_t), 0); + + if (sendfile(sock, image_file, (off_t *) &request.offset, request.size) < 0) + printf("ERROR: sendfile returned -1\n"); + + break; + + default: + printf("ERROR: Unknown command\n"); + break; + } + + } + close(sock); + printf("INFO: Client exit.\n"); + pthread_exit((void *) 0); +} + +int dnbd3_setup_socket() +{ + int sock; + struct sockaddr_in server; + + // Create socket + sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock < 0) + { + printf("ERROR: Socket failure\n"); + return -1; + } + + memset(&server, 0, sizeof(server)); + server.sin_family = AF_INET; // IPv4 + server.sin_addr.s_addr = htonl(INADDR_ANY); // Take all IPs + server.sin_port = htons(PORT); // set port number + + // Bind to socket + if (bind(sock, (struct sockaddr*) &server, sizeof(server)) < 0) + { + printf("ERROR: Bind failure\n"); + return -1; + } + + // Listen on socket + if (listen(sock, 50) == -1) + { + printf("ERROR: Listen failure\n"); + return -1; + } + + return sock; +} -- cgit v1.2.3-55-g7522