Merge branch 'master' into debian
[nbd.git] / nbdsrv.h
blob8010ced9c70e0f16d40a8fe5f7bc0a35b197d954
1 #ifndef NBDSRV_H
2 #define NBDSRV_H
4 #include <glib.h>
5 #include <stdbool.h>
6 #include <stdint.h>
8 #include <sys/socket.h>
9 #include <sys/types.h>
11 /* Structures */
13 /**
14 * Types of virtuatlization
15 **/
16 typedef enum {
17 VIRT_NONE=0, /**< No virtualization */
18 VIRT_IPLIT, /**< Literal IP address as part of the filename */
19 VIRT_IPHASH, /**< Replacing all dots in an ip address by a / before
20 doing the same as in IPLIT */
21 VIRT_CIDR, /**< Every subnet in its own directory */
22 } VIRT_STYLE;
24 /**
25 * Variables associated with a server.
26 **/
27 typedef struct {
28 gchar* exportname; /**< (unprocessed) filename of the file we're exporting */
29 off_t expected_size; /**< size of the exported file as it was told to
30 us through configuration */
31 gchar* listenaddr; /**< The IP address we're listening on */
32 unsigned int port; /**< port we're exporting this file at */
33 char* authname; /**< filename of the authorization file */
34 int flags; /**< flags associated with this exported file */
35 int socket; /**< The socket of this server. */
36 int socket_family; /**< family of the socket */
37 VIRT_STYLE virtstyle;/**< The style of virtualization, if any */
38 uint8_t cidrlen; /**< The length of the mask when we use
39 CIDR-style virtualization */
40 gchar* prerun; /**< command to be ran after connecting a client,
41 but before starting to serve */
42 gchar* postrun; /**< command that will be ran after the client
43 disconnects */
44 gchar* servename; /**< name of the export as selected by nbd-client */
45 int max_connections; /**< maximum number of opened connections */
46 gchar* transactionlog;/**< filename for transaction log */
47 } SERVER;
49 /**
50 * Variables associated with a client connection
52 typedef struct {
53 off_t exportsize; /**< size of the file we're exporting */
54 char *clientname; /**< peer, in human-readable format */
55 struct sockaddr_storage clientaddr; /**< peer, in binary format, network byte order */
56 char *exportname; /**< (processed) filename of the file we're exporting */
57 GArray *export; /**< array of FILE_INFO of exported files;
58 array size is always 1 unless we're
59 doing the multiple file option */
60 int net; /**< The actual client socket */
61 SERVER *server; /**< The server this client is getting data from */
62 char* difffilename; /**< filename of the copy-on-write file, if any */
63 int difffile; /**< filedescriptor of copyonwrite file. @todo
64 shouldn't this be an array too? (cfr export) Or
65 make -m and -c mutually exclusive */
66 uint32_t difffilelen; /**< number of pages in difffile */
67 uint32_t *difmap; /**< see comment on the global difmap for this one */
68 gboolean modern; /**< client was negotiated using modern negotiation protocol */
69 int transactionlogfd;/**< fd for transaction log */
70 int clientfeats; /**< Features supported by this client */
71 } CLIENT;
73 /* Constants and macros */
75 /**
76 * Error domain common for all NBD server errors.
77 **/
78 #define NBDS_ERR g_quark_from_static_string("server-error-quark")
80 /**
81 * NBD server error codes.
82 **/
83 typedef enum {
84 NBDS_ERR_CFILE_NOTFOUND, /**< The configuration file is not found */
85 NBDS_ERR_CFILE_MISSING_GENERIC, /**< The (required) group "generic" is missing */
86 NBDS_ERR_CFILE_KEY_MISSING, /**< A (required) key is missing */
87 NBDS_ERR_CFILE_VALUE_INVALID, /**< A value is syntactically invalid */
88 NBDS_ERR_CFILE_VALUE_UNSUPPORTED, /**< A value is not supported in this build */
89 NBDS_ERR_CFILE_NO_EXPORTS, /**< A config file was specified that does not
90 define any exports */
91 NBDS_ERR_CFILE_INCORRECT_PORT, /**< The reserved port was specified for an
92 old-style export. */
93 NBDS_ERR_CFILE_DIR_UNKNOWN, /**< A directory requested does not exist*/
94 NBDS_ERR_CFILE_READDIR_ERR, /**< Error occurred during readdir() */
95 NBDS_ERR_SO_LINGER, /**< Failed to set SO_LINGER to a socket */
96 NBDS_ERR_SO_REUSEADDR, /**< Failed to set SO_REUSEADDR to a socket */
97 NBDS_ERR_SO_KEEPALIVE, /**< Failed to set SO_KEEPALIVE to a socket */
98 NBDS_ERR_GAI, /**< Failed to get address info */
99 NBDS_ERR_SOCKET, /**< Failed to create a socket */
100 NBDS_ERR_BIND, /**< Failed to bind an address to socket */
101 NBDS_ERR_LISTEN, /**< Failed to start listening on a socket */
102 NBDS_ERR_SYS, /**< Underlying system call or library error */
103 } NBDS_ERRS;
106 * Logging macros.
108 * @todo remove this. We should use g_log in all cases, and use the
109 * logging mangler to redirect to syslog if and when necessary.
111 #ifdef ISSERVER
112 #define msg(prio, ...) syslog(prio, __VA_ARGS__)
113 #else
114 #define msg(prio, ...) g_log(G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, __VA_ARGS__)
115 #endif
116 #define MY_NAME "nbd_server"
118 /* Functions */
121 * Check whether a given address matches a given netmask.
123 * @param mask the address or netmask to check against, in ASCII representation
124 * @param addr the address to check, in network byte order
125 * @param af the address family of the passed address (AF_INET or AF_INET6)
127 * @return true if the address matches the mask, false otherwise; in case of
128 * failure to parse netmask, returns false with err set appropriately.
129 * @todo decide what to do with v6-mapped IPv4 addresses.
131 bool address_matches(const char* mask, const void* addr, int af, GError** err);
134 * Gets a byte to allow for address masking.
136 * @param masklen the length of the requested mask.
137 * @return if the length of the mask is 8 or longer, 0xFF. Otherwise, a byte
138 * with `masklen' number of leading bits set to 1, everything else set to 0.
140 uint8_t getmaskbyte(int masklen) G_GNUC_PURE;
143 * Check whether a client is allowed to connect. Works with an authorization
144 * file which contains one line per machine or network, with CIDR-style
145 * netmasks.
147 * @param opts The client who's trying to connect.
148 * @return 0 - authorization refused, 1 - OK
150 int authorized_client(CLIENT *opts);
153 * duplicate server
154 * @param s the old server we want to duplicate
155 * @return new duplicated server
157 SERVER* dup_serve(const SERVER *const s);
160 * append new server to array
161 * @param s server
162 * @param a server array
163 * @return 0 success, -1 error
165 int append_serve(const SERVER *const s, GArray *const a);
168 * Detect the size of a file.
170 * @param fhandle An open filedescriptor
171 * @return the size of the file, or OFFT_MAX if detection was
172 * impossible.
174 off_t size_autodetect(int fhandle);
175 #endif //NBDSRV_H