Commit Graph

93 Commits (49eaca0c42a15e1053355af4c96a4bee11cd4be3)

Author SHA1 Message Date
Ronnie Sahlberg 6f4ff8621f Handle POLLERR/POLLHUP properly and try to reconnect on failure
POLLERR and POLLHUP handling in rpc_service() could not deal with
session failures or auto reconnect.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2015-12-28 08:02:15 -08:00
Ronnie Sahlberg 034c277c71 Make rpc->connect_cb a one-shot callback
It makes no sense to have socket.c keep invoking this callback over and over.
Just change it to become one-shot.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2015-12-24 18:01:19 -08:00
Ronnie Sahlberg aea2810c1e Do not use ioctl(FIONREAD) for UDP sockets
The linux kernel does not check the UDP checksum until the application tries
to read if from the socket.

This means that the socket might be readable, but when we try to read
the data, or inspect how much data is available, the packets will be discarded
by the kernel.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2015-12-24 12:21:33 -08:00
Ronnie Sahlberg 1ec2d0c5b7 Add check that we have the full RM before starting to read the PDU data
If we are trying to read (part of?) the RM, we can not assume that as long
as recv() returned non-error that we have the full RM.
We must check before we proceed to try to read the actual PDU data.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2015-12-24 12:06:45 -08:00
Ronnie Sahlberg f681a2c167 Revert some commits that cause subtle API issues
We can not have a static rpc->inbuf buffer since that will no longer guarantee
that the received buffer is valid for the duration of callbacks.

One of the problems is that if we issue new (sync) RPCs from within a
callback, that will overwrite and invalidate the receive buffer that
we passed to the callback.

Revert "init: do not leak rpc->inbuf"
This reverts commit f7bc4c8bb1.

Revert "socket: we have to use memmove in rpc_read_from_socket"
This reverts commit 24429e95b8.

Revert "socket: make rpc->inbuf static and simplify receive logic"
This reverts commit 7000a0aa04.
2015-12-24 12:06:22 -08:00
Ronnie Sahlberg d73d4f3305 rpc_reconnect_requeue: return -1 if autoreconnect is not enabled
This funciton is called from rpc_service when it has detected that
a socket has errored out during reading/writing.
However, since this fucntion returns 0 (==success) for the case where
autoreconnect is not enabled, this means that for an errored socket we
will return 0 (==success) from rpc_service() back to the application.

Change rpc_reconnect_requeue to return -1 when invoked and autoreconnect
is disabled so that applications will receive an error back from rpc_service.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2015-10-19 18:57:17 -07:00
Peter Lieven ddd9e2f7e9 socket: keep fd the same across reconnects
There is no guarantee that we get the same fd again when
reestablishing a session. But if the fd changes during a
reconnect we might up with a client application busy polling
on the old fd.

Qemu registers a read handler on the current fd, but is
not realizing fd changes. So we busy poll on the old fd for good.
Things are working (except for the busy polling) until
a drain all is issued. At this point Qemu deadlocks.

Signed-off-by: Peter Lieven <pl@kamp.de>
2015-09-22 14:54:48 +02:00
Peter Lieven 7b7aef6b6d socket: keep reconnecting if a reconnect fails
otherwise we end up eating up all socket errors in rpc_service and then
believe we are connected, but the next call to rpc_read_from_socket
fails because the socket is closed. we then reconnect anyway.

Signed-off-by: Peter Lieven <pl@kamp.de>
2015-09-22 14:40:59 +02:00
Ronnie Sahlberg 2a95006567 Merge pull request #122 from plieven/fix_recv
socket: also reconnect on write errors
2015-09-06 06:57:32 -07:00
Peter Lieven 5c7a0f04e6 socket: fix deadlock in rpc_reconnect_requeue
the requeueing code is broken because we access pdu->next
after we mangled it in rpc_return_to_queue.

This leads to losing of waitqueue elements and more severe
a deadlock as soon as more than one waitpdu queue has elements.

Reason for that is that the first elements of the first
two queues are linked to each other.

Example:
waitpdu[0]->head = pduA ; pduA->next = pduB; pduB->next = NULL;
waitpdu[1]->head = pduC ; pduC->next = NULL;
outqueue->head = NULL;

After the for loop for waitpdu[0] queue the outqueue looks like

outqueue->head = pduA; pduA->next = NULL;

At this point pduB is lost!

In the for loop for waitpdu[1] queue the outqueue looks like this
after the first iteration:

outqueue->head = pduC; pduC->next = pduA; pduA->next = NULL;

We now fetch pdu->next of pduC which is pduA.

In the next iteration we put pduA in front of pduC. pduA->next
is then pduC and pduC->next is pduA. => Deadlock.

Signed-off-by: Peter Lieven <pl@kamp.de>
2015-08-28 21:13:37 +02:00
Peter Lieven aacee393ca socket: also reconnect on write errors
This also return -1 for rpc_service if rpc_reconnect_requeue fails.

Signed-off-by: Peter Lieven <pl@kamp.de>
2015-08-06 09:53:49 +02:00
Peter Lieven b319b976dc socket: handle count == 0 in rpc_read_from_socket
An EOF is signalled through a POLLIN event and subsequen recvs return
always 0. Handle this condition and reconnect. Otherwise we might
deadlock here.

Signed-off-by: Peter Lieven <pl@kamp.de>
2015-08-04 14:55:28 +02:00
Peter Lieven 9bff07490f add basic support for setting a log level
only logging to stderr is supported at the moment. Per default
there is no output. Its possible to set the log level via
debug url parameter.

Example:
 nfs-ls nfs://127.0.0.1/export?debug=2

Signed-off-by: Peter Lieven <pl@kamp.de>
2015-06-23 08:55:11 +02:00
Peter Lieven 24429e95b8 socket: we have to use memmove in rpc_read_from_socket
I was errornously believing that the areas could not overlap.

Signed-off-by: Peter Lieven <pl@kamp.de>
2015-06-19 15:54:54 +02:00
Peter Lieven beaa838637 fix some compiler warnings
Signed-off-by: Peter Lieven <pl@kamp.de>
2015-06-19 13:49:17 +02:00
Peter Lieven 7000a0aa04 socket: make rpc->inbuf static and simplify receive logic
Signed-off-by: Peter Lieven <pl@kamp.de>
2015-06-19 13:45:26 +02:00
Peter Lieven 82aec93f12 socket: limit memory allocation when reading from socket
the write limit of libnfs has been 1M since a long time.
Restrict rtmax and wrmax to 1M and error out otherwise.

Limit the PDU size when reading from socket to rule out
malicious servers forcing us to allocate a lot of memory.

Signed-off-by: Peter Lieven <pl@kamp.de>
2015-06-19 13:45:20 +02:00
Peter Lieven dc70b92dc6 socket: reset written bytes for head outqueue element
We could be in the middle of writing a PDU while we start reconnecting.

Signed-off-by: Peter Lieven <pl@kamp.de>
2015-06-19 13:45:15 +02:00
Peter Lieven cf420d32d0 socket: use FIONREAD ioctl only for UDP
under Linux poll might return POLLIN even if there are no bytes available for read.
See select(2) manpage for surious readiness under BUGS.

As a consequence we start dropping TCP connections which are still alive.

Signed-off-by: Peter Lieven <pl@kamp.de>

Conflicts:
	lib/socket.c
2015-06-19 13:45:03 +02:00
Peter Lieven 99ae3c01c4 add some debug output
Signed-off-by: Peter Lieven <pl@kamp.de>
2015-06-19 13:43:55 +02:00
Ronnie Sahlberg 63d40b1737 Revert "Remove unused variable from socket.c"
This reverts commit d74a938775.
2015-03-12 20:52:52 -07:00
MilhouseVH d74a938775 Remove unused variable from socket.c 2015-03-12 05:29:56 +00:00
Ronnie Sahlberg 84607f4821 Add -Wall -Werror and friends
Update the configure to add some sanity -W arguments.
A good start is probably :
  -Wall -Werror -Wshadow -Wno-write-strings -Wstrict-prototypes
  -Wpointer-arith -Wcast-align -Wno-strict-aliasing

Fixup the paces in the code that triggers.
(one of which is readahead code which is perhaps broken?)

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2015-03-10 21:06:38 -07:00
Mike Cui ac76768170 set_tcp_sockopt should be static, otherwise it prevents linking with libiscsi
which has function of the same name, also not static.

Same fix needs to go in to libiscsi.
2015-01-05 09:25:27 -08:00
Ronnie Sahlberg cc3e372de4 socket.c: we need netinet/in.h on some platforms 2014-08-14 18:56:39 -07:00
Mike Frysinger 10a1a78115 fix implicit decl warnings
Include the proper headers to fix warnings like:
libnfs-sync.c:1529:3: warning: implicit declaration of function 'gettimeofday' [-Wimplicit-function-declaration]
libnfs-zdr.c:506:2: warning: implicit declaration of function 'getuid' [-Wimplicit-function-declaration]

Signed-off-by: Mike Frysinger <vapier@gentoo.org>

sys/time.h needs to be protected with an ifdef

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2014-08-11 06:08:05 -07:00
Petr Salinger 18c94b4633 Use sockaddr_in6 instead of sockaddr6_in 2014-07-19 18:07:13 +02:00
Peter Lieven 7a750aea1c socket: fix broken connect for non broadcast traffic
commit 1c1e09a completely broke connects for non broadcast
traffic since it forgot to copy the server address into
the socket_storage struct.

Signed-off-by: Peter Lieven <pl@kamp.de>
2014-06-08 14:20:12 +02:00
Ronnie Sahlberg a87bb233a8 Merge branch 'xid-hash' 2014-04-10 19:59:28 -07:00
Memphiz 74b037ec46 [socket] - disable linger by setting SO_LINGER to 0 seconds 2014-04-10 20:34:11 +02:00
Mark Hills 63f36a0923 Track waiting requests in a hash table, by xid
NFS servers can respond to requests in any order, and they do. In our
tests there is also some clustering to the responses; it could be
because eg. requests are served synchronously if the data is in the cache.

Introduce a hash table so that we are able to find the pdu quickly in
all cases, assuming random distribution of the responses.
2014-04-03 17:52:21 -07:00
Mark Hills aec45c6274 Optimisations to the pdu queues
When making many concurrent requests (as is likely in any performance
criticial application), the use of SLIST_REMOVE and SLIST_ADD_END are
a severe bottleneck because of their linear search.

I considered using a double-linked list but it was unnecessary to
allocate the additional memory for each list entry.

Instead, continue to use a single-linked list but retain:

* a pointer to the end of the list; and
* a pointer to the previous entry during a linear search.

The former would makes append operations O(1) time, and the latter
does the same for removal. We can do this because removal only happens
within the linear search, and there is no random access to the queue.
2014-04-03 17:51:04 -07:00
Ronnie Sahlberg 1c1e09ad51 IPV6: Add basic IPv6 support
This adds basic IPv6 support to libnfs.
Since libnfs currently only support PORTMAPPER protocol up to version 2
the IPv6 support only works if the server runs Both MOUNT and NFS protocols
on the same ports for IPv6 as for IPv4.

To get full IPv6 support we need to add support for PORTMAPPER version 3
and use it for discovery when using IPv6
2014-03-19 18:25:49 -07:00
Arne Redlich 60af7e19d1 rpc_read_from_socket: fix use-after-free due to missing return
Spotted by clang analyzer.

Signed-off-by: Arne Redlich <arne.redlich@googlemail.com>
2014-02-19 18:59:44 -08:00
Arne Redlich 8907aea9eb socket.c: fix format string issues (too few arguments)
These were uncovered by the previously added __attribute__((format(printf))).

Emacs also removed trailing whitespace while at it.

Signed-off-by: Arne Redlich <arne.redlich@googlemail.com>
2014-02-19 18:59:17 -08:00
Ronnie Sahlberg 6ec481d3fa Add a rpc_set_fd() fucntion which can be used to swap the underlying socket file descriptor
This is mainly needed when having to track and control the file descriptors that are used by libnfs, for example when trying to emulate dup2() ontop
of libnfs.
2014-02-02 08:45:21 -08:00
Peter Lieven d43a8953f5 make adjustments for v6 of the qemu NFS driver
Signed-off-by: Peter Lieven <pl@kamp.de>
2014-01-13 11:22:21 +01:00
Peter Lieven 1c8b4547ce add tcp-syncnt URL param to adjust TCP_SYNCNT sockopt
This allows indirect support for a configurable connect timeout.

Linux uses a exponential backoff for SYN retries starting
with 1 second.

This means for a value n for TCP_SYNCNT, the connect will
effectively timeout after 2^(n+1)-1 seconds.

Example:
 examples/nfs-ls nfs://10.0.0.1/export?tcp-syncnt=1

Signed-off-by: Peter Lieven <pl@kamp.de>
2013-12-23 14:03:18 +01:00
Ronnie Sahlberg 751770fd43 Dont leak every single buffer we read from the socket. 2013-10-30 18:15:03 -07:00
Ronnie Sahlberg dd97d43aad Reset the receive buffer processing the received PDU.
This allows us to have recursive eventloops and do synchronous
rpc calls from a callback.
2013-10-20 13:16:45 -07:00
Ronnie Sahlberg c022471e52 Add configure test for arpa/inet.h 2013-05-28 21:25:08 -07:00
Ronnie Sahlberg bff8fe460d Some more configure checks for headers 2013-05-28 17:54:12 -07:00
Ronnie Sahlberg 7057e733c1 Add configure checks for sys/socket.h 2013-05-28 17:43:47 -07:00
Ronnie Sahlberg cb5b8be2eb Try making the initial port used a little more random 2013-05-28 17:22:28 -07:00
Ronnie Sahlberg 00748f36c5 more header include cleanups 2013-04-14 10:11:48 -07:00
Ronnie Sahlberg 2142af5d47 WIN32: More ifdef cleanups 2013-04-14 09:02:23 -07:00
Ronnie Sahlberg 622489d36e WIN32: get rid of some ifdefs 2013-04-14 08:50:38 -07:00
Ronnie Sahlberg 099be710b6 SOCKET: Use recv/send for all socket io on all platforms
instead of only on windows and aros  and read/write on the others
2013-04-14 08:43:59 -07:00
Ronnie Sahlberg 9a9126c3d9 AROS: add inet_pton emulation and make sure we use recv/send and not read/write 2013-04-13 07:40:46 -07:00
Ronnie Sahlberg d7c6e9aaa9 Initial AROS support.
The test app doesnt link yet since we are missing a bunch of symbols

but it is a start
2013-04-10 20:28:40 -07:00