From 868fec1f8eca7c344fc9ac057b7418331299d9ce Mon Sep 17 00:00:00 2001 From: Lars Müller Date: Sat, 1 Mar 2008 18:30:38 +0000 Subject: Import dnbd* from the former openslx-contrib repo as of revision 92. openslx-contrib is currently read only and will get removed in some days. git-svn-id: http://svn.openslx.org/svn/openslx/contrib/dnbd/trunk@1592 95ad53e4-c205-0410-b2fa-d234c58c8868 --- server/net.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 server/net.c (limited to 'server/net.c') diff --git a/server/net.c b/server/net.c new file mode 100644 index 0000000..02db9aa --- /dev/null +++ b/server/net.c @@ -0,0 +1,147 @@ +/* + * net.c - network stuff for the server + * Copyright (C) 2006 Thorsten Zitterell + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define DNBD_USERSPACE 1 +#include "../common/dnbd-cliserv.h" + +#include "net.h" + +struct listener_s { + pthread_t tid; + net_request_t *request; +}; + +typedef struct listener_s listener_t; +listener_t listener; + +/* + * function net_tx(): send a server reply + */ +void net_tx(net_info_t * net_info, net_reply_t * reply) +{ + if (sendto + (net_info->sock, reply->data, reply->len, 0, + (struct sockaddr *) &net_info->groupnet, + sizeof(net_info->groupnet)) < 0) + fprintf(stderr, "net_tx: mcast sendproblem\n"); + +} + +/* + * function net_rx(): receive a client request + * returns: 1 on correct size of reply, otherwise 0 + */ +int net_rx(net_info_t * net_info, net_request_t * request) +{ + ssize_t n; + + request->clientlen = sizeof(request->client); + + n = recvfrom(net_info->sock, &request->data, + sizeof(request->data), 0, + &request->client, &request->clientlen); + + /* sizeof of request must be size of a DNBD request */ + return (n == sizeof(request->data) ? 1 : 0); +} + +/* + * function net_init(): initialize network for multicast + * returns: structure with network related information + */ +net_info_t *net_init(const char *mnet) +{ + struct ip_mreq mreq; + const int ttl = 64; /* TTL of 64 should be enough */ + u_char loop = 0; + + net_info_t *net_info = NULL; + + net_info = (net_info_t *) malloc(sizeof(net_info_t)); + if (!net_info) + return NULL; + + memset(net_info, 0, sizeof(net_info_t)); + + /* network setup */ + net_info->server.sin_family = AF_INET; + net_info->server.sin_port = htons(DNBD_PORT); + net_info->sock = socket(PF_INET, SOCK_DGRAM, 0); + + if (!inet_aton(mnet, &net_info->server.sin_addr)) { + fprintf(stderr, + "ERROR: multicast group %s is not a valid address!\n", + mnet); + goto out_free; + } + + if (bind + (net_info->sock, (struct sockaddr *) &net_info->server, + sizeof(net_info->server)) < 0) { + fprintf(stderr, "ERROR: binding socket!\n"); + goto out_free; + } + + if (!inet_aton(mnet, &net_info->groupnet.sin_addr)) { + fprintf(stderr, + "ERROR: multicast group %s is not a valid address!\n", + mnet); + goto out_free; + } + + /* multicast setup */ + net_info->groupnet.sin_family = AF_INET; + net_info->groupnet.sin_port = htons(DNBD_PORT); + + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + memcpy(&mreq.imr_multiaddr, &net_info->groupnet.sin_addr, + sizeof(struct in_addr)); + + if (setsockopt + (net_info->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, + sizeof(mreq)) < 0) { + fprintf(stderr, + "ERROR: cannot add multicast membership!\n"); + goto out_free; + } + + if (setsockopt(net_info->sock, IPPROTO_IP, IP_MULTICAST_TTL, + &ttl, sizeof(ttl)) < 0) { + fprintf(stderr, "ERROR: Setting TTL to 2\n"); + goto out_free; + } + + /* no looping, please */ + if (setsockopt + (net_info->sock, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, + sizeof(loop)) < 0) { + fprintf(stderr, + "ERROR: cannot disable multicast looping!\n"); + goto out_free; + } + + goto out; + + out_free: + fprintf(stderr, + "hint: check kernel multicast support, multicast routing\n"); + if (net_info) + free(net_info); + + net_info = NULL; + out: + return net_info; +} -- cgit v1.2.3-55-g7522