Network Block Device @PACKAGE_VERSION@

nbdsrv.h

Go to the documentation of this file.
00001 #ifndef NBDSRV_H
00002 #define NBDSRV_H
00003 
00004 #include "lfs.h"
00005 
00006 #include <glib.h>
00007 #include <stdbool.h>
00008 #include <stdint.h>
00009 
00010 #include <sys/socket.h>
00011 #include <sys/types.h>
00012 
00013 /* Structures */
00014 
00015 /**
00016  * Types of virtuatlization
00017  **/
00018 typedef enum {
00019         VIRT_NONE=0,    /**< No virtualization */
00020         VIRT_IPLIT,     /**< Literal IP address as part of the filename */
00021         VIRT_IPHASH,    /**< Replacing all dots in an ip address by a / before
00022                              doing the same as in IPLIT */
00023         VIRT_CIDR,      /**< Every subnet in its own directory */
00024 } VIRT_STYLE;
00025 
00026 /**
00027  * Variables associated with a server.
00028  **/
00029 typedef struct {
00030         gchar* exportname;    /**< (unprocessed) filename of the file we're exporting */
00031         uint64_t expected_size; /**< size of the exported file as it was told to
00032                                us through configuration */
00033         gchar* listenaddr;   /**< The IP address we're listening on */
00034         unsigned int port;   /**< port we're exporting this file at */
00035         char* authname;      /**< filename of the authorization file */
00036         int flags;           /**< flags associated with this exported file */
00037         int socket;          /**< The socket of this server. */
00038         int socket_family;   /**< family of the socket */
00039         VIRT_STYLE virtstyle;/**< The style of virtualization, if any */
00040         uint8_t cidrlen;     /**< The length of the mask when we use
00041                                   CIDR-style virtualization */
00042         gchar* prerun;       /**< command to be ran after connecting a client,
00043                                   but before starting to serve */
00044         gchar* postrun;      /**< command that will be ran after the client
00045                                   disconnects */
00046         gchar* servename;    /**< name of the export as selected by nbd-client */
00047         int max_connections; /**< maximum number of opened connections */
00048         gchar* transactionlog;/**< filename for transaction log */
00049 } SERVER;
00050 
00051 /**
00052   * Variables associated with a client connection
00053   */
00054 typedef struct {
00055         uint64_t exportsize;    /**< size of the file we're exporting */
00056         char *clientname;    /**< peer, in human-readable format */
00057         struct sockaddr_storage clientaddr; /**< peer, in binary format, network byte order */
00058         char *exportname;    /**< (processed) filename of the file we're exporting */
00059         GArray *export;    /**< array of FILE_INFO of exported files;
00060                                array size is always 1 unless we're
00061                                doing the multiple file option */
00062         int net;             /**< The actual client socket */
00063         SERVER *server;      /**< The server this client is getting data from */
00064         char* difffilename;  /**< filename of the copy-on-write file, if any */
00065         int difffile;        /**< filedescriptor of copyonwrite file. @todo
00066                                shouldn't this be an array too? (cfr export) Or
00067                                make -m and -c mutually exclusive */
00068         uint32_t difffilelen;     /**< number of pages in difffile */
00069         uint32_t *difmap;            /**< see comment on the global difmap for this one */
00070         gboolean modern;     /**< client was negotiated using modern negotiation protocol */
00071         int transactionlogfd;/**< fd for transaction log */
00072         int clientfeats;     /**< Features supported by this client */
00073 } CLIENT;
00074 
00075 /* Constants and macros */
00076 
00077 /**
00078  * Error domain common for all NBD server errors.
00079  **/
00080 #define NBDS_ERR g_quark_from_static_string("server-error-quark")
00081 
00082 /**
00083  * NBD server error codes.
00084  **/
00085 typedef enum {
00086         NBDS_ERR_CFILE_NOTFOUND,          /**< The configuration file is not found */
00087         NBDS_ERR_CFILE_MISSING_GENERIC,   /**< The (required) group "generic" is missing */
00088         NBDS_ERR_CFILE_KEY_MISSING,       /**< A (required) key is missing */
00089         NBDS_ERR_CFILE_VALUE_INVALID,     /**< A value is syntactically invalid */
00090         NBDS_ERR_CFILE_VALUE_UNSUPPORTED, /**< A value is not supported in this build */
00091         NBDS_ERR_CFILE_NO_EXPORTS,        /**< A config file was specified that does not
00092                                                define any exports */
00093         NBDS_ERR_CFILE_INCORRECT_PORT,    /**< The reserved port was specified for an
00094                                                old-style export. */
00095         NBDS_ERR_CFILE_DIR_UNKNOWN,       /**< A directory requested does not exist*/
00096         NBDS_ERR_CFILE_READDIR_ERR,       /**< Error occurred during readdir() */
00097         NBDS_ERR_SO_LINGER,               /**< Failed to set SO_LINGER to a socket */
00098         NBDS_ERR_SO_REUSEADDR,            /**< Failed to set SO_REUSEADDR to a socket */
00099         NBDS_ERR_SO_KEEPALIVE,            /**< Failed to set SO_KEEPALIVE to a socket */
00100         NBDS_ERR_GAI,                     /**< Failed to get address info */
00101         NBDS_ERR_SOCKET,                  /**< Failed to create a socket */
00102         NBDS_ERR_BIND,                    /**< Failed to bind an address to socket */
00103         NBDS_ERR_LISTEN,                  /**< Failed to start listening on a socket */
00104         NBDS_ERR_SYS,                     /**< Underlying system call or library error */
00105 } NBDS_ERRS;
00106 
00107 /**
00108   * Logging macros.
00109   *
00110   * @todo remove this. We should use g_log in all cases, and use the
00111   * logging mangler to redirect to syslog if and when necessary.
00112   */
00113 #ifdef ISSERVER
00114 #define msg(prio, ...) syslog(prio, __VA_ARGS__)
00115 #else
00116 #define msg(prio, ...) g_log(G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, __VA_ARGS__)
00117 #endif
00118 #define MY_NAME "nbd_server"
00119 
00120 /* Functions */
00121 
00122 /**
00123   * Check whether a given address matches a given netmask.
00124   *
00125   * @param mask the address or netmask to check against, in ASCII representation
00126   * @param addr the address to check, in network byte order
00127   * @param af the address family of the passed address (AF_INET or AF_INET6)
00128   *
00129   * @return true if the address matches the mask, false otherwise; in case of
00130   * failure to parse netmask, returns false with err set appropriately.
00131   * @todo decide what to do with v6-mapped IPv4 addresses.
00132   */
00133 bool address_matches(const char* mask, const void* addr, int af, GError** err);
00134 
00135 /**
00136   * Gets a byte to allow for address masking.
00137   *
00138   * @param masklen the length of the requested mask.
00139   * @return if the length of the mask is 8 or longer, 0xFF. Otherwise, a byte
00140   * with `masklen' number of leading bits set to 1, everything else set to 0.
00141   */
00142 uint8_t getmaskbyte(int masklen) G_GNUC_PURE;
00143 
00144 /**
00145  * Check whether a client is allowed to connect. Works with an authorization
00146  * file which contains one line per machine or network, with CIDR-style
00147  * netmasks.
00148  *
00149  * @param opts The client who's trying to connect.
00150  * @return 0 - authorization refused, 1 - OK
00151  **/
00152 int authorized_client(CLIENT *opts);
00153 
00154 /**
00155  * duplicate server
00156  * @param s the old server we want to duplicate
00157  * @return new duplicated server
00158  **/
00159 SERVER* dup_serve(const SERVER *const s);
00160 
00161 /**
00162  * append new server to array
00163  * @param s server
00164  * @param a server array
00165  * @return 0 success, -1 error
00166  */
00167 int append_serve(const SERVER *const s, GArray *const a);
00168 
00169 /**
00170  * Detect the size of a file.
00171  *
00172  * @param fhandle An open filedescriptor
00173  * @return the size of the file, or UINT64_MAX if detection was
00174  * impossible.
00175  **/
00176 uint64_t size_autodetect(int fhandle);
00177 #endif //NBDSRV_H