ReactOS 0.4.15-dev-6712-g46b4b55
nfs41_server.c
Go to the documentation of this file.
1/* NFSv4.1 client for Windows
2 * Copyright 2012 The Regents of the University of Michigan
3 *
4 * Olga Kornievskaia <aglo@umich.edu>
5 * Casey Bodley <cbodley@umich.edu>
6 *
7 * This library is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2.1 of the License, or (at
10 * your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * without any warranty; without even the implied warranty of merchantability
14 * or fitness for a particular purpose. See the GNU Lesser General Public
15 * License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 */
21
22#include <windows.h>
23#include <strsafe.h>
24#include <stdio.h>
25
26#include "wintirpc.h"
27#include "rpc/rpc.h"
28
29#include "name_cache.h"
30#include "daemon_debug.h"
31#include "nfs41.h"
32#include "util.h"
33
34
35#define SRVLVL 2 /* dprintf level for server logging */
36
37
38/* nfs41_server_list */
42};
44
45#define server_entry(pos) list_container(pos, nfs41_server, entry)
46
47
49{
52}
53
54/* http://tools.ietf.org/html/rfc5661#section-1.6
55 * 1.6. General Definitions: Server Owner:
56 * "When the client has two connections each to a peer with the same major
57 * identifier, the client assumes that both peers are the same server (the
58 * server namespace is the same via each connection)" */
59
60/* http://tools.ietf.org/html/rfc5661#section-2.10.4
61 * 2.10.4. Server Scope
62 * "When the server scope values are the same, server owner value may be
63 * validly compared. In cases where the server scope values are different,
64 * server owner values are treated as different even if they contain all
65 * identical bytes." */
66
67/* given these definitions, we require that both the server_owner.major_id
68 * and server_scope are identical when matching instances of nfs41_server */
69
71 const char *scope;
72 const char *owner;
73};
74
75static int server_compare(
76 const struct list_entry *entry,
77 const void *value)
78{
80 const struct server_info *info = (const struct server_info*)value;
81 const int diff = strncmp(server->scope, info->scope, NFS4_OPAQUE_LIMIT);
82 return diff ? diff : strncmp(server->owner, info->owner, NFS4_OPAQUE_LIMIT);
83}
84
86 IN struct server_list *servers,
87 IN const struct server_info *info,
88 OUT struct list_entry **entry_out)
89{
90 *entry_out = list_search(&servers->head, info, server_compare);
91 return *entry_out ? NO_ERROR : ERROR_FILE_NOT_FOUND;
92}
93
94static int server_create(
95 IN const struct server_info *info,
96 OUT nfs41_server **server_out)
97{
98 int status = NO_ERROR;
100
101 server = calloc(1, sizeof(nfs41_server));
102 if (server == NULL) {
104 eprintf("failed to allocate server %s\n", info->owner);
105 goto out;
106 }
107
110 InitializeSRWLock(&server->addrs.lock);
111 nfs41_superblock_list_init(&server->superblocks);
112
113 status = nfs41_name_cache_create(&server->name_cache);
114 if (status) {
115 eprintf("nfs41_name_cache_create() failed with %d\n", status);
116 goto out_free;
117 }
118out:
119 *server_out = server;
120 return status;
121
122out_free:
123 free(server);
124 server = NULL;
125 goto out;
126}
127
128static void server_free(
130{
131 dprintf(SRVLVL, "server_free(%s)\n", server->owner);
132 nfs41_superblock_list_free(&server->superblocks);
133 nfs41_name_cache_free(&server->name_cache);
134 free(server);
135}
136
137static __inline void server_ref_locked(
139{
140 server->ref_count++;
141 dprintf(SRVLVL, "nfs41_server_ref(%s) count %d\n",
142 server->owner, server->ref_count);
143}
144
147{
149
151
153}
154
157{
159
160 server->ref_count--;
161 dprintf(SRVLVL, "nfs41_server_deref(%s) count %d\n",
162 server->owner, server->ref_count);
163 if (server->ref_count == 0) {
164 list_remove(&server->entry);
166 }
167
169}
170
172 IN OUT struct server_addrs *addrs,
173 IN const netaddr4 *addr)
174{
175 /* we keep a list of addrs used to connect to each server. once it gets
176 * bigger than NFS41_ADDRS_PER_SERVER, overwrite the oldest addrs. use
177 * server_addrs.next_index to implement a circular array */
178
179 AcquireSRWLockExclusive(&addrs->lock);
180
181 if (multi_addr_find(&addrs->addrs, addr, NULL)) {
182 dprintf(SRVLVL, "server_addrs_add() found existing addr '%s'.\n",
183 addr->uaddr);
184 } else {
185 /* overwrite the address at 'next_index' */
186 StringCchCopyA(addrs->addrs.arr[addrs->next_index].netid,
187 NFS41_NETWORK_ID_LEN+1, addr->netid);
188 StringCchCopyA(addrs->addrs.arr[addrs->next_index].uaddr,
190
191 /* increment/wrap next_index */
192 addrs->next_index = (addrs->next_index + 1) % NFS41_ADDRS_PER_SERVER;
193 /* update addrs.count if necessary */
194 if (addrs->addrs.count < addrs->next_index)
195 addrs->addrs.count = addrs->next_index;
196
197 dprintf(SRVLVL, "server_addrs_add() added new addr '%s'.\n",
198 addr->uaddr);
199 }
200 ReleaseSRWLockExclusive(&addrs->lock);
201}
202
205 OUT multi_addr4 *addrs)
206{
207 struct server_addrs *saddrs = &server->addrs;
208 uint32_t i, j;
209
210 /* make a copy of the server's addrs, with most recent first */
211 AcquireSRWLockShared(&saddrs->lock);
212 j = saddrs->next_index;
213 for (i = 0; i < saddrs->addrs.count; i++) {
214 /* decrement/wrap j */
216 memcpy(&addrs->arr[i], &saddrs->addrs.arr[j], sizeof(netaddr4));
217 }
218 ReleaseSRWLockShared(&saddrs->lock);
219}
220
222 IN const char *server_owner_major_id,
223 IN const char *server_scope,
224 IN const netaddr4 *addr,
225 OUT nfs41_server **server_out)
226{
227 struct server_info info;
228 struct list_entry *entry;
230 int status;
231
232 info.owner = server_owner_major_id;
233 info.scope = server_scope;
234
235 dprintf(SRVLVL, "--> nfs41_server_find_or_create(%s)\n", info.owner);
236
238
239 /* search for an existing server */
241 if (entry == NULL) {
242 /* create a new server */
244 if (status == NO_ERROR) {
245 /* add it to the list */
246 list_add_tail(&g_server_list.head, &server->entry);
247 *server_out = server;
248
249 dprintf(SRVLVL, "<-- nfs41_server_find_or_create() "
250 "returning new server %p\n", server);
251 } else {
252 dprintf(SRVLVL, "<-- nfs41_server_find_or_create() "
253 "returning %d\n", status);
254 }
255 } else {
258
259 dprintf(SRVLVL, "<-- nfs41_server_find_or_create() "
260 "returning existing server %p\n", server);
261 }
262
263 if (server) {
264 /* register the address used to connect */
265 server_addrs_add(&server->addrs, addr);
266
268 }
269
270 *server_out = server;
272 return status;
273}
274
276 IN const char *hostname,
277 IN unsigned short port,
278 OUT multi_addr4 *addrs)
279{
281 char service[16];
282 struct addrinfo hints = { 0 }, *res, *info;
283 struct netconfig *nconf;
284 struct netbuf addr;
285 char *netid, *uaddr;
286
287 dprintf(SRVLVL, "--> nfs41_server_resolve(%s:%u)\n",
288 hostname, port);
289
290 addrs->count = 0;
291
292 StringCchPrintfA(service, 16, "%u", port);
293
294 /* request a list of tcp addrs for the given hostname,port */
295 hints.ai_family = AF_UNSPEC;
296 hints.ai_socktype = SOCK_STREAM;
297 hints.ai_protocol = IPPROTO_TCP;
298
299 if (getaddrinfo(hostname, service, &hints, &res) != 0)
300 goto out;
301
302 for (info = res; info != NULL; info = info->ai_next) {
303 /* find the appropriate entry in /etc/netconfig */
304 switch (info->ai_family) {
305 case AF_INET: netid = "tcp"; break;
306 case AF_INET6: netid = "tcp6"; break;
307 default: continue;
308 }
309
310 nconf = getnetconfigent(netid);
311 if (nconf == NULL)
312 continue;
313
314 /* convert to a transport-independent universal address */
315 addr.buf = info->ai_addr;
316 addr.maxlen = addr.len = (unsigned int)info->ai_addrlen;
317
318 uaddr = taddr2uaddr(nconf, &addr);
319 freenetconfigent(nconf);
320
321 if (uaddr == NULL)
322 continue;
323
324 StringCchCopyA(addrs->arr[addrs->count].netid,
325 NFS41_NETWORK_ID_LEN+1, netid);
326 StringCchCopyA(addrs->arr[addrs->count].uaddr,
327 NFS41_UNIVERSAL_ADDR_LEN+1, uaddr);
328 freeuaddr(uaddr);
329
331 if (++addrs->count >= NFS41_ADDRS_PER_SERVER)
332 break;
333 }
335out:
336 if (status)
337 dprintf(SRVLVL, "<-- nfs41_server_resolve(%s:%u) returning "
338 "error %d\n", hostname, port, status);
339 else
340 dprintf(SRVLVL, "<-- nfs41_server_resolve(%s:%u) returning "
341 "%s\n", hostname, port, addrs->arr[0].uaddr);
342 return status;
343}
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * hostname
Definition: ftp.c:88
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static struct list_entry * list_search(const struct list_entry *head, const void *value, list_compare_fn compare)
Definition: list.h:102
static void list_init(struct list_entry *head)
Definition: list.h:51
bool_t multi_addr_find(IN const multi_addr4 *addrs, IN const netaddr4 *addr, OUT OPTIONAL uint32_t *index_out)
Definition: util.c:218
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
#define NO_ERROR
Definition: dderror.h:5
#define free
Definition: debug_ros.c:5
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
VOID WINAPI InitializeSRWLock(PSRWLOCK Lock)
Definition: sync.c:75
USHORT port
Definition: uri.c:228
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define IPPROTO_TCP
Definition: ip.h:196
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
void freenetconfigent(struct netconfig *netconfigp)
Definition: getnetconfig.c:530
struct netconfig * getnetconfigent(char *netid) const
Definition: getnetconfig.c:432
GLuint res
Definition: glext.h:9613
GLenum const GLvoid * addr
Definition: glext.h:9621
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
uint32_t entry
Definition: isohybrid.c:63
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
int nfs41_name_cache_create(OUT struct nfs41_name_cache **cache_out)
Definition: name_cache.c:752
int nfs41_name_cache_free(IN struct nfs41_name_cache **cache_out)
Definition: name_cache.c:796
void nfs41_superblock_list_init(IN nfs41_superblock_list *superblocks)
void nfs41_superblock_list_free(IN nfs41_superblock_list *superblocks)
#define NFS41_ADDRS_PER_SERVER
Definition: nfs41_const.h:49
#define NFS41_UNIVERSAL_ADDR_LEN
Definition: nfs41_const.h:53
#define NFS41_NETWORK_ID_LEN
Definition: nfs41_const.h:56
#define NFS4_OPAQUE_LIMIT
Definition: nfs41_const.h:31
#define server_entry(pos)
Definition: nfs41_server.c:45
int nfs41_server_find_or_create(IN const char *server_owner_major_id, IN const char *server_scope, IN const netaddr4 *addr, OUT nfs41_server **server_out)
Definition: nfs41_server.c:221
static void server_free(IN nfs41_server *server)
Definition: nfs41_server.c:128
void nfs41_server_deref(IN nfs41_server *server)
Definition: nfs41_server.c:155
static __inline void server_ref_locked(IN nfs41_server *server)
Definition: nfs41_server.c:137
void nfs41_server_list_init()
Definition: nfs41_server.c:48
int nfs41_server_resolve(IN const char *hostname, IN unsigned short port, OUT multi_addr4 *addrs)
Definition: nfs41_server.c:275
static int server_entry_find(IN struct server_list *servers, IN const struct server_info *info, OUT struct list_entry **entry_out)
Definition: nfs41_server.c:85
#define SRVLVL
Definition: nfs41_server.c:35
static void server_addrs_add(IN OUT struct server_addrs *addrs, IN const netaddr4 *addr)
Definition: nfs41_server.c:171
static struct server_list g_server_list
Definition: nfs41_server.c:43
static int server_compare(const struct list_entry *entry, const void *value)
Definition: nfs41_server.c:75
void nfs41_server_addrs(IN nfs41_server *server, OUT multi_addr4 *addrs)
Definition: nfs41_server.c:203
static int server_create(IN const struct server_info *info, OUT nfs41_server **server_out)
Definition: nfs41_server.c:94
void nfs41_server_ref(IN nfs41_server *server)
Definition: nfs41_server.c:145
#define dprintf
Definition: regdump.c:33
static FILE * out
Definition: regtests2xml.c:44
#define calloc
Definition: rosglue.h:14
char * taddr2uaddr(const struct netconfig *nconf, const struct netbuf *nbuf)
Definition: rpc_generic.c:609
void freeuaddr(char *uaddr)
Definition: rpc_generic.c:628
namespace GUID const ADDRINFOEXW * hints
Definition: sock.c:80
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145
STRSAFEAPI StringCchPrintfA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszFormat,...)
Definition: strsafe.h:520
netaddr4 arr[NFS41_ADDRS_PER_SERVER]
Definition: nfs41_types.h:91
uint32_t count
Definition: nfs41_types.h:92
Definition: list.h:27
Definition: types.h:144
uint32_t next_index
Definition: nfs41.h:75
multi_addr4 addrs
Definition: nfs41.h:74
SRWLOCK lock
Definition: nfs41.h:76
const char * owner
Definition: nfs41_server.c:72
const char * scope
Definition: nfs41_server.c:71
struct list_entry head
Definition: nfs41_server.c:40
CRITICAL_SECTION lock
Definition: nfs41_server.c:41
Definition: ps.c:97
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
#define IN
Definition: typedefs.h:39
#define OUT
Definition: typedefs.h:40
Definition: pdh_main.c:94
static rfbScreenInfoPtr server
Definition: vnc.c:74
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define ERROR_BAD_NET_NAME
Definition: winerror.h:159
#define AF_INET6
Definition: winsock.h:369
#define AF_UNSPEC
Definition: winsock.h:344
#define getaddrinfo
Definition: wspiapi.h:44
#define freeaddrinfo
Definition: wspiapi.h:46