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