summaryrefslogtreecommitdiffstats
path: root/src/server/net.c
diff options
context:
space:
mode:
authorJohann Latocha2012-01-31 23:52:24 +0100
committerJohann Latocha2012-01-31 23:52:24 +0100
commit63519d6ae4cb20ae4871310e09a28fd59f5c9fc7 (patch)
treee285221e909058628332a736e42cbc864de4ac39 /src/server/net.c
parent[ALL] Reformat (line wrapping, indent) (diff)
downloaddnbd3-63519d6ae4cb20ae4871310e09a28fd59f5c9fc7.tar.gz
dnbd3-63519d6ae4cb20ae4871310e09a28fd59f5c9fc7.tar.xz
dnbd3-63519d6ae4cb20ae4871310e09a28fd59f5c9fc7.zip
[ALL] Some refactoring
Diffstat (limited to 'src/server/net.c')
-rw-r--r--src/server/net.c133
1 files changed, 133 insertions, 0 deletions
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 <johann@latocha.de>
+ *
+ * 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 <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/sendfile.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#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;
+}