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 } SERVER;
50 
51 /**
52  * Variables associated with a client connection
53  */
54 typedef struct {
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 */
73 } CLIENT;
74 
75 /* Constants and macros */
76 
77 /**
78  * Error domain common for all NBD server errors.
79  **/
80 #define NBDS_ERR g_quark_from_static_string("server-error-quark")
81 
82 /**
83  * NBD server error codes.
84  **/
85 typedef enum {
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
92  define any exports */
93  NBDS_ERR_CFILE_INCORRECT_PORT, /**< The reserved port was specified for an
94  old-style export. */
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 */
105 } NBDS_ERRS;
106 
107 /**
108  * Logging macros.
109  *
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.
112  */
113 #ifdef ISSERVER
114 #define msg(prio, ...) syslog(prio, __VA_ARGS__)
115 #else
116 #define msg(prio, ...) g_log(G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, __VA_ARGS__)
117 #endif
118 #define MY_NAME "nbd_server"
119 
120 /* Functions */
121 
122 /**
123  * Check whether a given address matches a given netmask.
124  *
125  * @param mask the address or netmask to check against, in ASCII representation
126  * @param addr the address to check, in network byte order
127  * @param af the address family of the passed address (AF_INET or AF_INET6)
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 void* addr, int af, 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 &quot;generic&quot; is missing.
Definition: nbdsrv.h:87
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&#39;re doing the multiple file opt...
Definition: nbdsrv.h:59
Variables associated with a server.
Definition: nbdsrv.h:29
uint8_t getmaskbyte(int masklen)
Gets a byte to allow for address masking.
Definition: nbdsrv.c:91
uint32_t difffilelen
number of pages in difffile
Definition: nbdsrv.h:68
SERVER * server
The server this client is getting data from.
Definition: nbdsrv.h:63
Failed to set SO_LINGER to a socket.
Definition: nbdsrv.h:97
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:72
NBDS_ERRS
NBD server error codes.
Definition: nbdsrv.h:85
Failed to bind an address to socket.
Definition: nbdsrv.h:102
Error occurred during readdir()
Definition: nbdsrv.h:96
The configuration file is not found.
Definition: nbdsrv.h:86
int flags
flags associated with this exported file
Definition: nbdsrv.h:36
Failed to start listening on a socket.
Definition: nbdsrv.h:103
A (required) key is missing.
Definition: nbdsrv.h:88
gchar * exportname
(unprocessed) filename of the file we&#39;re exporting
Definition: nbdsrv.h:30
int net
The actual client socket.
Definition: nbdsrv.h:62
Underlying system call or library error.
Definition: nbdsrv.h:104
unsigned int port
port we&#39;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&#39;re listening on.
Definition: nbdsrv.h:33
Failed to set SO_KEEPALIVE to a socket.
Definition: nbdsrv.h:99
char * clientname
peer, in human-readable format
Definition: nbdsrv.h:56
int socket
The socket of this server.
Definition: nbdsrv.h:37
Variables associated with a client connection.
Definition: nbdsrv.h:54
int difffile
filedescriptor of copyonwrite file.
Definition: nbdsrv.h:65
Failed to get address info.
Definition: nbdsrv.h:100
SERVER * dup_serve(const SERVER *const s)
duplicate server
Definition: nbdsrv.c:148
uint32_t * difmap
see comment on the global difmap for this one
Definition: nbdsrv.h:69
VIRT_STYLE
Types of virtuatlization.
Definition: nbdsrv.h:18
uint64_t size_autodetect(int fhandle)
Detect the size of a file.
Definition: nbdsrv.c:251
Literal IP address as part of the filename.
Definition: nbdsrv.h:20
int transactionlogfd
fd for transaction log
Definition: nbdsrv.h:71
void err(const char *s) G_GNUC_NORETURN
Definition: cliserv.h:120
The reserved port was specified for an old-style export.
Definition: nbdsrv.h:93
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:98
int append_serve(const SERVER *const s, GArray *const a)
append new server to array
Definition: nbdsrv.c:191
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
bool address_matches(const char *mask, const void *addr, int af, GError **err)
Check whether a given address matches a given netmask.
Definition: nbdsrv.c:25
uint64_t exportsize
size of the file we&#39;re exporting
Definition: nbdsrv.h:55
char * authname
filename of the authorization file
Definition: nbdsrv.h:35
gboolean modern
client was negotiated using modern negotiation protocol
Definition: nbdsrv.h:70
A config file was specified that does not define any exports.
Definition: nbdsrv.h:91
char * difffilename
filename of the copy-on-write file, if any
Definition: nbdsrv.h:64
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:90
A directory requested does not exist.
Definition: nbdsrv.h:95
char * exportname
(processed) filename of the file we&#39;re exporting
Definition: nbdsrv.h:58
A value is syntactically invalid.
Definition: nbdsrv.h:89
Failed to create a socket.
Definition: nbdsrv.h:101
int authorized_client(CLIENT *opts)
Check whether a client is allowed to connect.
Definition: nbdsrv.c:103