socket->priv->timeout is only a guint, and the multiplication is
performed before it’s widened to gint64 to be stored in start_time
(thanks, C). This means any timeout of 50 days or more would overflow.
Fixing this bug makes me feel a real sense of self-worth.
Coverity ID: 1159478
Signed-off-by: Philip Withnall <withnall@endlessm.com>
WSAWaitForMultipleEvents() only returns for one of the waiting threads, and
that one might not even be the one waiting for the condition that changed. As
such, only let a single thread wait on the event and use a GCond for all other
threads.
With this it is possible to e.g. have an UDP socket that is written to from
one thread and read from in another thread on Win32 too. On POSIX systems this
was working before already.
https://bugzilla.gnome.org/show_bug.cgi?id=762283
If we have an input parameter (or return value) we need to use (nullable).
However, if it is an (inout) or (out) parameter, (optional) is sufficient.
It looks like (nullable) could be used for everything according to the
Annotation documentation, but (optional) is more specific.
If g_socket_receive_message_with_timeout() is called with messages ==
NULL set the msg_control buffer to empty to not request the control
messages from recvmsg() at all.
This completely disables the control message processing and reduces
overhead, which might be critical at high packet rate.
https://bugzilla.gnome.org/show_bug.cgi?id=774520
GDatagramBased is an interface abstracting datagram-based communications
in the style of the Berkeley sockets API. It may be contrasted to (for
example) GIOStream, which supports only streaming I/O.
GDatagramBased allows socket-like communications to be done through any
object, not just a concrete GSocket (which wraps socket()).
This adds the GDatagramBased interface, and implements it in GSocket.
https://bugzilla.gnome.org/show_bug.cgi?id=697907
Commit a0cefc2217 introduced an unresolved
symbol, g_socket_send_message_with_timeout(), on win32. Windows
unfortunately isn’t clever enough to fill in the gaps and magic up the
implementation of that function from nowhere, so we had better do it
ourselves.
Factor the blocking behaviour out of g_socket_send_message() into a new
internal g_socket_send_message_with_timeout().
https://bugzilla.gnome.org/show_bug.cgi?id=756054
5d68947 factored out resuable items, but some of these are only for
*NIX builds, which will break the build on Windows. Fix this by
building these portions only when !G_OS_WIN32.
https://bugzilla.gnome.org/show_bug.cgi?id=756053
The value of g_socket_is_connected() gets stuck high if the GSocket is
shut down in two steps:
g_socket_shutdown (socket, TRUE, FALSE, NULL);
g_socket_shutdown (socket, FALSE, TRUE, NULL);
rather than one:
g_socket_shutdown (socket, TRUE, TRUE, NULL);
Fix that by tracking the connected status for the read half and the
write half of the connection separately.
https://bugzilla.gnome.org/show_bug.cgi?id=697907
If an error in the underlying sendmmsg() syscall occurs after
successfully sending one or more messages, g_socket_send_messages()
should return the number of messages successfully sent, rather than an
error. This mirrors the documented sendmmsg() behaviour.
This is a slight behaviour change for g_socket_send_messages(), but as
it relaxes the error reporting (reporting errors in fewer situations
than before), it should not cause problems.
https://bugzilla.gnome.org/show_bug.cgi?id=751924
Add support for receiving multiple messages with a single system call,
using recvmmsg() if available. Otherwise, fall back to looping over
g_socket_receive_message().
This adds new API, g_socket_receive_messages(), and corresponding unit
tests.
https://bugzilla.gnome.org/show_bug.cgi?id=751924
In order to support per-operation timeouts on new API like
g_socket_receive_messages(), the internal GSocket API should use
timeouts rather than boolean blocking parameters.
(timeout == 0) === (blocking == FALSE)
(timeout == -1) === (blocking == TRUE)
(timeout > 0) === new behaviour
https://bugzilla.gnome.org/show_bug.cgi?id=751924
The API design here is a bit awkward — the in/out flags argument should
actually have been an in flags argument and an out msg_flags argument.
Clarify that a bit in the documentation.
https://bugzilla.gnome.org/show_bug.cgi?id=751924
If @error is NULL then we don't even need to evaluate the remaining
arguments. And if errno is EWOULDBLOCK, then no one should see the
error message anyway, so don't bother g_strdup_printf'ing up a pretty
one.
https://bugzilla.gnome.org/show_bug.cgi?id=752769
This code was out of date with current coding practices.
Nowadays it's common to receive file descriptors over environment
variables from other processes like systemd. The unit files that
control these file descriptors are configurable by sysadmins.
It is not (necessarily) a programmer error when g_socket_details_from_fd()
is called with a file descriptor that is not a socket. It can also
be a system and/or configuration error.
https://bugzilla.gnome.org/show_bug.cgi?id=746339
For performance reasons we should always try to send or
receive our messages first and only wait for more space
or data to become available if we get an EAGAIN (and
are in blocking mode).
https://bugzilla.gnome.org/show_bug.cgi?id=751122
Currently, the Windows code use Winsock2-specific APIs to try to emulate
calls such as inet_pton(), inet_ntop() and if_nametoindex(), which may not
do the job all the time. On Vista and later, Winsock2 does provide a
proper implementation for these functions, so we can use them if they exist
on the system, by querying for them during g_networking_init(). Otherwise,
we continue to use the original code path for these, in the case of XP and
Server 2003.
This enables many of the network-address tests to pass on Windows as a
result, when the native Winsock2 implementations can be used.
https://bugzilla.gnome.org/show_bug.cgi?id=730352
When implementing blocking operations on top of
nonblocking sockets we should always first try to
perform the operation and then if needed handle
EAGAIN and wait with g_socket_wait_condition.
This is an optimization since we avoid calling
wait condition when it is not needed, but most
importantly this fixes hangs on win32 where some
events (in particular FD_WRITE) are only emitted
after the operation fails with EWOULDBLOCK.
https://bugzilla.gnome.org/show_bug.cgi?id=732439https://bugzilla.gnome.org/show_bug.cgi?id=741707
Allows sending of multiple messages (packets, datagrams)
in one go using sendmmsg(), thus drastically reducing the
number of syscalls when sending out a lot of data, or when
sending out the same data to multiple recipients.
https://bugzilla.gnome.org/show_bug.cgi?id=719646
This is a best-effort approach to preventing SIGPIPE emissions on Darwin
and iOS, where they continue to be intercepted by the Xcode debugger
even if SIG_IGN prevents them crashing the program.
This is similar to the existing code which sets MSG_NOSIGNAL on all
send() calls. MSG_NOSIGNAL doesn't exist on Darwin though.
Based on a patch from Philip Withnall.
https://bugzilla.gnome.org/show_bug.cgi?id=728730
This is quite important, as it means you can safely let the GSocket drop
out of scope while maintaining a reference to the GSource, and the
socket will remain open. That means fewer closure structures, simpler
code, and fewer allocations.
https://bugzilla.gnome.org/show_bug.cgi?id=732081
Rather than having special code in gsocket.c, handle Winsock errors
along with other Win32 errors in gioerror.c
Also, reference g_win32_error_message() from the
g_io_error_from_win32_error() docs, and update the
g_win32_error_message() docs to clarify that it works with Winsock
error codes too.
There is no longer any code left in the check/prepare functions on UNIX,
so put %NULL in the GSourceFuncs vtable.
This also allows us to simplify some logic.
https://bugzilla.gnome.org/show_bug.cgi?id=724707
We are reusing the GPollFD.revents field of the source to store a
temporary value. Use a local variable for that instead.
This is a refactor to make the next commit easier to understand.
https://bugzilla.gnome.org/show_bug.cgi?id=724707
Now that GCancellable's GSource is based on _set_ready_time() instead of
an fd, we should use it as a child source, instead of forcing the
creation of the fd and adding it as a poll.
https://bugzilla.gnome.org/show_bug.cgi?id=724707
After getting an EINTR, g_socket_condition_timed_wait() has to adjust
its timeout, but it was trying to convert from nanoseconds to
microseconds by multiplying by 1000 rather than dividing... Oops.
https://bugzilla.gnome.org/show_bug.cgi?id=724239
Windows needs a special inefficient hack to implement
g_socket_get_available() correctly for UDP sockets, but that hack
isn't needed for TCP, and in fact, might give the wrong answer in that
case. Fix it to only use the hack with UDP.
Also, fix that case to handle non-blocking sockets as well.
And add a test case for g_socket_get_available() with TCP.
https://bugzilla.gnome.org/show_bug.cgi?id=723422
Since all element markup is now gone from the doc comments,
we can turn off the gtk-doc sgml mode, which means that from
now on, docbook markup is no longer allowed in doc comments.
To make this possible, we have to replace all remaining
entities in doc comments by their replacement text, & -> &
and so on.
Assume unix platforms support the original POSIX.1 standard.
Specifically, assume that if G_OS_UNIX, then we have chown(),
getcwd(), getgrgid(), getpwuid(), link(), <grp.h>, <pwd.h>,
<sys/types.h>, <sys/uio.h>, <sys/wait.h>, and <unistd.h>.
Additionally, since all versions of Windows that we care about also
have <sys/types.h>, we can remove HAVE_SYS_TYPES_H checks everywhere.
Also remove one include of <sys/times.h>, and the corresponding
configure check, since the include is not currently needed (and may
always have just been a typo for <sys/time.h>).
https://bugzilla.gnome.org/show_bug.cgi?id=710519
Rather than having lots of obscure platform-based #ifdefs all over
gio, define some macros in gcredentialsprivate.h, and use those to
simplify the rest of the code.
https://bugzilla.gnome.org/show_bug.cgi?id=701482
On Windows and OS X, FIONREAD on a UDP socket gets the total number of
bytes available, not the number of bytes available in the next packet,
which is the more useful number (and how the function always behaved
on Linux).
On OS X, fix this by using SO_NREAD. On Windows, fix this by doing a
MSG_PEEK recv() into a giant buffer, since there is apparently no
other way to get the information.
https://bugzilla.gnome.org/show_bug.cgi?id=686786
The requested_conditions list access is not threadsafe. When passing
the socket ownership from a GSource callback to another thread, which
also creates a GSocketSource for the socket, it can happen that the
original GSocketSource is finalized at the same time as the new one
is created. This would cause inconsistencies in the requested_conditions
list and can cause assertions or completely undefined behaviour.
https://bugzilla.gnome.org/show_bug.cgi?id=705027
With UDP sockets, g_socket_bind() with allow_reuse=TRUE on Linux
behaved in a way that the documentation didn't suggest, and that
didn't match other OSes. (Specifically, it allowed binding multiple
multicast sockets to the same address.)
Since this behavior is useful, and since allow_reuse didn't have any
other meaning with UDP sockets, update the docs to reflect the Linux
behavior, and make it do the same thing on non-Linux.
https://bugzilla.gnome.org/show_bug.cgi?id=689245
GPollableSource and GSocket's "broken" source never trigger on their
own, so with the changes to GSources in the last cycle, their check
and prepare functions are unnecessary (and undesired).
https://bugzilla.gnome.org/show_bug.cgi?id=701511
For the glib-defined source types, and any source type that defines a
closure callback but not a closure marshal, use
g_cclosure_marshal_generic. And then remove all the other remaining
source closure marshals.
https://bugzilla.gnome.org/show_bug.cgi?id=701511
As it turns out, we have examples of internal functions called
type_name_get_private() in the wild (especially among older libraries),
so we need to use a name for the per-instance private data getter
function that hopefully won't conflict with anything.
Use the same code GSocket does, to try SOCK_CLOEXEC first, and then
fall back to FD_CLOEXEC if it fails. (And fix that code to not call
fcntl if SOCK_CLOEXEC worked.)
https://bugzilla.gnome.org/show_bug.cgi?id=692332
As RFC 2292 points out, some platforms (e.g. Darwin 9.8.0) provide
CMSG_FIRSTHDR(msg) which just returns msg.msg_control without first
checking if msg.msg_controllen is non-zero. We need a workaround for
such platforms not to let g_socket_receive_message() segfault.
https://bugzilla.gnome.org/show_bug.cgi?id=690388
On IPv6 sockets, set both the IPv4 and IPv6 versions of IP socket
options, in case the socket is (or might become) IPv4-wrapped. (But
ignore errors when setting the IPv4 version.)
Similarly, when joining or leaving a multicast group, pick the sockopt
to use based on the address family of the multicast address rather
than the address family of the socket.
https://bugzilla.gnome.org/show_bug.cgi?id=687092
Add g_socket_get_option() and g_socket_set_option(), wrapping
getsockopt/setsockopt for the case of integer-valued options. Update
code to use these instead of the underlying calls.
https://bugzilla.gnome.org/show_bug.cgi?id=623187
Install a public "gnetworking.h" header that can be used to include
the relevant OS-dependent networking headers. This does not really
abstract away unix-vs-windows however; error codes, in particular,
are incompatible.
gnetworkingprivate.h now contains just a few internal URI-related
functions
Also add a g_networking_init() function to gnetworking.h, which can be
used to explicitly initialize OS-level networking, rather than having
that happen as a side-effect of registering GInetAddress.
https://bugzilla.gnome.org/show_bug.cgi?id=623187
Re-#define a few socket functions to work around winsock's prototypes
having, eg, "int *" rather than "unsigned int *", or "char *" rather
than "void *".
(Also fix two places that mistakenly assumed guint==guint32.)
https://bugzilla.gnome.org/show_bug.cgi?id=688109
Darwin's poll doesn't change revents if there are no available events, though it returns 0. Initialize the fd.revents to 0 so that the test passes.
That reveals a test failure, though, because with socket streams it takes time for an event to pass through the socket. Provide an 80-usec delay to allow time for the propagation.
Solaris/OpenSolaris/OpenIndiana define FIONREAD in sys/filio.h.
This commit adds a configure check for this header, and includes
it conditionally in gio/gsocket.c.
Patch by Fabian Groffen, bug 675524.
If all members of GSocketFamily are supported on the platform, then
all of its values will be positive, and so the enum might become
unsigned, in which case testing for "family < 0" might cause warnings.
But we want to return an error if family == 0 (aka
G_SOCKET_FAMILY_INVALID) anyway, so just tweak the test accordingly.
https://bugzilla.gnome.org/show_bug.cgi?id=674592
This is needed because glib-mkenums doesn't handle #ifdef values in
enums, and so it needs to have all values always defined in the enum.
When not available, define the missing values to a negative value.
Unix and Windows gio GSocket behaves differently when the socket is
closed by the peer. On Unix, the client receives pending data before
receiving HUP. But on Windows, the HUP may come before, resulting in
unreliable and racy code. We should have same behaviour on all
platforms.
According to MSDN documentation: "an application should check for
remaining data upon receipt of FD_CLOSE to avoid any possibility of
losing data."
https://bugzilla.gnome.org/show_bug.cgi?id=669810
Some platforms don't have the source-specific multicast sockopts, and
so would fail to compile. Fix that (and return an error if the caller
tries to use source-specific). Also clarify the docs a bit.
https://bugzilla.gnome.org/show_bug.cgi?id=668468
Apparently IPV6_JOIN_GROUP and IPV6_LEAVE_GROUP are more portable than
IPV6_ADD_MEMBERSHIP and IPV6_DROP_MEMBERSHIP. (Windows and Linux have
both, but OS X only has the latter.)
g_socket_receive_with_blocking() and g_socket_send_with_blocking claim
to return -1 in error, their return type is gssize, and yet they
return FALSE if the initial g_return_val_if_fail() call fails.
https://bugzilla.gnome.org/show_bug.cgi?id=667226