|
Network Block Device @PACKAGE_VERSION@
|
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
1.7.3