10 #include <sys/socket.h>
11 #include <sys/types.h>
16 * Types of virtuatlization
19 VIRT_NONE
=0, /**< No virtualization */
20 VIRT_IPLIT
, /**< Literal IP address as part of the filename */
21 VIRT_IPHASH
, /**< Replacing all dots in an ip address by a / before
22 doing the same as in IPLIT */
23 VIRT_CIDR
, /**< Every subnet in its own directory */
27 * Variables associated with a server.
30 gchar
* exportname
; /**< (unprocessed) filename of the file we're exporting */
31 uint64_t expected_size
; /**< size of the exported file as it was told to
32 us through configuration */
33 gchar
* listenaddr
; /**< The IP address we're listening on */
34 unsigned int port
; /**< port we're exporting this file at */
35 char* authname
; /**< filename of the authorization file */
36 int flags
; /**< flags associated with this exported file */
37 int socket
; /**< The socket of this server. */
38 int socket_family
; /**< family of the socket */
39 VIRT_STYLE virtstyle
;/**< The style of virtualization, if any */
40 uint8_t cidrlen
; /**< The length of the mask when we use
41 CIDR-style virtualization */
42 gchar
* prerun
; /**< command to be ran after connecting a client,
43 but before starting to serve */
44 gchar
* postrun
; /**< command that will be ran after the client
46 gchar
* servename
; /**< name of the export as selected by nbd-client */
47 int max_connections
; /**< maximum number of opened connections */
48 gchar
* transactionlog
;/**< filename for transaction log */
52 * Variables associated with a client connection
55 uint64_t exportsize
; /**< size of the file we're exporting */
56 char *clientname
; /**< peer, in human-readable format */
57 struct sockaddr_storage clientaddr
; /**< peer, in binary format, network byte order */
58 char *exportname
; /**< (processed) filename of the file we're exporting */
59 GArray
*export
; /**< array of FILE_INFO of exported files;
60 array size is always 1 unless we're
61 doing the multiple file option */
62 int net
; /**< The actual client socket */
63 SERVER
*server
; /**< The server this client is getting data from */
64 char* difffilename
; /**< filename of the copy-on-write file, if any */
65 int difffile
; /**< filedescriptor of copyonwrite file. @todo
66 shouldn't this be an array too? (cfr export) Or
67 make -m and -c mutually exclusive */
68 uint32_t difffilelen
; /**< number of pages in difffile */
69 uint32_t *difmap
; /**< see comment on the global difmap for this one */
70 gboolean modern
; /**< client was negotiated using modern negotiation protocol */
71 int transactionlogfd
;/**< fd for transaction log */
72 int clientfeats
; /**< Features supported by this client */
75 /* Constants and macros */
78 * Error domain common for all NBD server errors.
80 #define NBDS_ERR g_quark_from_static_string("server-error-quark")
83 * NBD server error codes.
86 NBDS_ERR_CFILE_NOTFOUND
, /**< The configuration file is not found */
87 NBDS_ERR_CFILE_MISSING_GENERIC
, /**< The (required) group "generic" is missing */
88 NBDS_ERR_CFILE_KEY_MISSING
, /**< A (required) key is missing */
89 NBDS_ERR_CFILE_VALUE_INVALID
, /**< A value is syntactically invalid */
90 NBDS_ERR_CFILE_VALUE_UNSUPPORTED
, /**< A value is not supported in this build */
91 NBDS_ERR_CFILE_NO_EXPORTS
, /**< A config file was specified that does not
93 NBDS_ERR_CFILE_INCORRECT_PORT
, /**< The reserved port was specified for an
95 NBDS_ERR_CFILE_DIR_UNKNOWN
, /**< A directory requested does not exist*/
96 NBDS_ERR_CFILE_READDIR_ERR
, /**< Error occurred during readdir() */
97 NBDS_ERR_SO_LINGER
, /**< Failed to set SO_LINGER to a socket */
98 NBDS_ERR_SO_REUSEADDR
, /**< Failed to set SO_REUSEADDR to a socket */
99 NBDS_ERR_SO_KEEPALIVE
, /**< Failed to set SO_KEEPALIVE to a socket */
100 NBDS_ERR_GAI
, /**< Failed to get address info */
101 NBDS_ERR_SOCKET
, /**< Failed to create a socket */
102 NBDS_ERR_BIND
, /**< Failed to bind an address to socket */
103 NBDS_ERR_LISTEN
, /**< Failed to start listening on a socket */
104 NBDS_ERR_SYS
, /**< Underlying system call or library error */
110 * @todo remove this. We should use g_log in all cases, and use the
111 * logging mangler to redirect to syslog if and when necessary.
114 #define msg(prio, ...) syslog(prio, __VA_ARGS__)
116 #define msg(prio, ...) g_log(G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, __VA_ARGS__)
118 #define MY_NAME "nbd_server"
123 * Check whether a given address matches a given netmask.
125 * @param mask the address or netmask to check against, in ASCII representation
126 * @param addr the address to check
128 * @return true if the address matches the mask, false otherwise; in case of
129 * failure to parse netmask, returns false with err set appropriately.
130 * @todo decide what to do with v6-mapped IPv4 addresses.
132 bool address_matches(const char* mask
, const struct sockaddr
* addr
, GError
** err
);
135 * Gets a byte to allow for address masking.
137 * @param masklen the length of the requested mask.
138 * @return if the length of the mask is 8 or longer, 0xFF. Otherwise, a byte
139 * with `masklen' number of leading bits set to 1, everything else set to 0.
141 uint8_t getmaskbyte(int masklen
) G_GNUC_PURE
;
144 * Check whether a client is allowed to connect. Works with an authorization
145 * file which contains one line per machine or network, with CIDR-style
148 * @param opts The client who's trying to connect.
149 * @return 0 - authorization refused, 1 - OK
151 int authorized_client(CLIENT
*opts
);
155 * @param s the old server we want to duplicate
156 * @return new duplicated server
158 SERVER
* dup_serve(const SERVER
*const s
);
161 * append new server to array
163 * @param a server array
164 * @return 0 success, -1 error
166 int append_serve(const SERVER
*const s
, GArray
*const a
);
169 * Detect the size of a file.
171 * @param fhandle An open filedescriptor
172 * @return the size of the file, or UINT64_MAX if detection was
175 uint64_t size_autodetect(int fhandle
);