summaryrefslogtreecommitdiff
path: root/agent
AgeCommit message (Collapse)AuthorFilesLines
2014-02-24agent: Expand documentation for a couple of NiceAgent functionsPhilip Withnall1-14/+22
Expand documentation for nice_agent_gather_candidates() and nice_agent_set_remote_credentials().
2014-02-24agent: Fix inlining of nice_debug() if NDEBUG is definedPhilip Withnall2-2/+10
2014-02-24agent: Assert on re-entrant readsPhilip Withnall1-0/+4
Ensure the agent’s context doesn’t get iterated while in the middle of reading a message, as that will corrupt the component->recv_messages state.
2014-02-24agent: Improve debug outputPhilip Withnall1-9/+18
2014-02-24agent: Add nice_input_message_iter_compare()Philip Withnall2-2/+24
Use it instead of memcmp() to avoid comparing padding bytes.
2014-02-21agent: returning 0 valid messages is valid, it means EOFOlivier Crête1-1/+0
2014-02-20iostream: iostreams are only for reliable streams, no need to checkOlivier Crête2-3/+2
2014-02-20agent: Use locally allocated memory if the application buffer is not big ↵Olivier Crête1-0/+55
enough for one STUN packet
2014-02-18outputstream: Trigger the pollable source on error or removalOlivier Crête2-2/+5
2014-02-13agent: Fix compiler warningsOlivier Crête2-5/+5
2014-01-31pseudotcp: Remove one duplicated call to g_get_monotonic_time()Olivier Crête1-8/+7
2014-01-31agent: Remove weak pointers, they aren't thread safe anywayOlivier Crête2-35/+46
And we get close to 10% perf boost
2014-01-31pseudotcp: Add list of unsent segmentOlivier Crête1-20/+29
Looping through the list of send segment was the only thing from libnice showing up in my profiler. Keeping a list of segment that were never sent has made it disappear.
2014-01-31agent: Avoid calling nice_address_to_string() when debugging is disabledOlivier Crête7-70/+82
2014-01-31pseudotcp: Use GQueue for list that has stuff inserted in the endOlivier Crête1-24/+22
2014-01-31pseudotcp: Don't change the receive buffer size if it hasnt changedOlivier Crête1-0/+3
2014-01-31agent: Restore the ability nice_agent_send() to send partial buffersOlivier Crête3-101/+134
This is very important for reliable mode. Also use it in the GOutputStream so as to not get into the case where there is still some space in the TCP buffer, but not enough for one message. Also warn against this problem.
2014-01-31agent: Replace nice_agent_build_io_stream() with nice_agent_get_io_stream()Olivier Crête4-27/+31
Also made the GIOStream into a singleton, it always returns the same one. Also make it impossible to create a GIOStream for a non-existing stream/component
2014-01-31Remove the "length" parameter from NiceOutputMessageOlivier Crête4-40/+63
It was used correctly only half the time anyway
2014-01-31Remove the "to" parameter from NiceOutputMessageOlivier Crête3-22/+10
We never send multiple messages to separate targets in practice, so this will simplify the code
2014-01-31agent: Attaching to a NULL context should attach to the default oneOlivier Crête1-3/+3
Otherwise it would have attached to a newly created context
2014-01-31agent: Add support for vectored I/O for sendsPhilip Withnall5-109/+175
Add one new public function, nice_agent_send_messages_nonblocking(), which replaces nice_agent_send_full(). This isn’t an API break, because nice_agent_send_full() hasn’t been in a release yet. The new API allows sending multiple messages in a single call, and supports vectors of buffers to transmit the messages from. The existing nice_agent_send() API has been left untouched, although it’s a bit of a bugbear because it’s non-blocking and doesn’t fit with the new *_nonblocking() naming scheme. Oh well. This doesn’t bring any notable changes to the number of memcpy()s on the critical path: it remains at zero for the common cases and common socket types. It introduces the possibility for future work to eliminate some memcpy()s in more complex socket types, like tcp-turn and tcp-bsd, but these optimisations have not been made yet. FIXME comments have been added. This includes modifications to the test-send-recv unit test to cover the new API.
2014-01-31socket: Add vectored I/O support for sending on socketsPhilip Withnall3-0/+50
Replace the send() API with a send_messages() API, which supports sending multiple messages, each with multiple buffers rather than a single monolithic buffer. This doesn’t break API, as the socket API is not exposed outside libnice. It does introduce a new struct: NiceOutputMessage, which is analogous to struct mmsghdr and NiceInputMessage. This includes updates to the test-bsd test to cover the changed API. The existing nice_socket_send() API has been retained as a thin wrapper around nice_socket_send_messages(), for convenience only. It’s hoped that internal usage of this API will decline to the point where it can be removed.
2014-01-31agent: Move gtk-doc comments from agent.c to agent.h for new APIPhilip Withnall2-124/+161
I completely disagree with this, and believe the C file is a much better place for them, as then they’re: • easier to read while hacking on the functions, and • easier to modify once finished hacking on the functions. I think the argument for putting them in the header files (so that the documentation is available by the function declarations) is weak, as the generated gtk-doc manual should be installed on the system alongside the header files in any case.
2014-01-31agent: Add support for vectored I/O for receivesPhilip Withnall7-315/+806
Add two new public functions: • nice_agent_recv_messages() • nice_agent_recv_messages_nonblocking() which allow receiving multiple messages in a single call, and support vectors of buffers to receive the messages into. The existing nice_agent_recv[_nonblocking]() APIs have been left untouched. This tidies up a lot of the message handling code internally, and eliminates a couple of memcpy()s. There are still a few more memcpy()s on the critical path, which could be eliminated with further work. In the reliable agent case, every message is memcpy()ed twice: once into the pseudo-TCP receive buffer, and once out of it. The copy on input could be eliminated (in the case of in-order delivery of packets) by receiving directly into the receive buffer. The copy on output can’t be eliminated except in the I/O callback case (when nice_agent_attach_recv() has been used), in which case the callback could be invoked with a pointer directly into the pseudo-TCP receive buffer. In the non-reliable agent case, zero memcpy()s are used. A couple of the more complex socket implementations (TURN and HTTP) have slow paths during setup, and partially also during normal use. These could be optimised further, and FIXME comments have been added.
2014-01-31stun: Add a fast version of stun_message_validate_buffer_length()Philip Withnall1-0/+7
stun_message_validate_buffer_length() is already fast, but requires the entire message to be in a single monolithic buffer. For introducing vectored I/O, this becomes impossible to guarantee. Rather than rewriting the STUN code to natively support vectors of buffers (which would be a huge undertaking, and would probably slow the code down considerably), implement a fast check of whether a message is likely to be a STUN packet which *does* support vectored I/O. This can then be used to determine whether to compact the vector of buffers to a single monolithic one in order to validate the message more thoroughly.
2014-01-31socket: Add vectored I/O support for receiving on socketsPhilip Withnall3-1/+140
Replace the recv() API with a recv_messages() API, which supports receiving multiple messages, each with multiple buffers rather than a single monolithic buffer. This doesn’t break API, as the socket API is not exposed outside libnice. It does introduce a new struct: NiceInputMessage, which is analogous to struct mmsghdr. This includes updates to the test-bsd test to cover the changed API.
2014-01-31agent: Simplify control flow in agent_recv_locked()Philip Withnall1-22/+23
This introduces no functional changes.
2014-01-31outputstream: Put GError in the right GError**Olivier Crête1-2/+2
2014-01-31component: Don't free the nice socket before detaching itOlivier Crête1-1/+1
2014-01-31agent: Make sure there is no integer overflow if the timeout is nowOlivier Crête1-3/+8
Make sure that if the timeout is now, no negative number is passed as an unsigned
2014-01-31pseudotcp: Don't fail when sending over 4GiB of dataOlivier Crête1-9/+15
Integer comparisons need to take care of rollovers
2014-01-31outputstream: Fix race between writable callback and GCond waitOlivier Crête1-3/+7
2014-01-31inputstream: Make the GSource hold a weak ref on the agentOlivier Crête3-37/+52
This also means that it can't have the component ref. Also make the cancellable a child source of this GPollableInputStream one
2014-01-31outputstream: Don't wake up on every input bufferOlivier Crête4-14/+35
So instead of actually blocking on the FD, block on a GCancellable which is triggered when the writable callback is called. Also set the application's GCancellable as a child of this source.
2014-01-31agent: Only change pseudotcp clock if the new timeout is soonerOlivier Crête3-18/+27
Destroying and creating GSources is expensive, so also don't destroy and re-create if possible, instead lets use the new g_source_set_ready_time()
2014-01-31pseudotcp: Switch to using monotonic timeOlivier Crête1-3/+1
2014-01-31outputstream: Release blocking send lock while sendingOlivier Crête1-0/+7
Otherwise it produces a deadlock
2014-01-31outputstream: Make the blocking send thread safeOlivier Crête1-26/+50
There was a possible race between disconnection and freeing of the WriteDatas structure, now it's ref-counted so it can never happen. Also set the len to -1 if the cancellable was cancelled.
2014-01-31agent: Return G_IO_ERROR_WOULD_BLOCK for non-connected pseudoTCPOlivier Crête1-2/+2
2014-01-31agent: Return cancelled if sending is cancelledOlivier Crête1-0/+3
2014-01-31nice: Add nice_agent_build_io_stream to exported symbolsOlivier Crête1-0/+1
2014-01-31agent: Queue incoming pseudo-TCP messages until ACKs can be sentPhilip Withnall3-1/+90
If pseudo-TCP messages are received before a socket has been selected from all the STUN candidates, they would previously be immediately passed to the pseudo-TCP state machine, which would attempt to send ACKs for them. This would fail (due to a lack of an outbound UDP socket), and would incur a retransmit timeout in the TCP state machine. This slowed down the tests enormously if one agent in a test completed candidate selection before the other (which is an entirely reasonable scenario). This never occurred before because the existing tests artificially run both agents in lock-step, and never send data packets from one to the other until both have completed candidate selection. This is basically cheating. Fix the problem by queuing incoming pseudo-TCP messages until an outbound UDP socket is available to send the ACKs or SYNACKs on.
2014-01-31agent: Correct maximum UDP data lengthPhilip Withnall1-6/+6
The maximum number of bytes in a UDP packet (ignoring problems like fragmentation and MTUs) is 65535 = 2^16-1 bytes, as the length field in the packet header is 16b wide.
2014-01-31agent: Slightly improve debugging outputPhilip Withnall1-6/+5
2014-01-31agent: Document correctness of io_mutex lockingPhilip Withnall3-3/+24
2014-01-31agent: Combine nice_agent_recv() and nice_agent_recv_nonblocking()Philip Withnall1-173/+100
Sharing is caring.
2014-01-31agent: Add a couple of comments to the pseudo-TCP implementationPhilip Withnall1-2/+3
2014-01-31agent: Hold a reference to pseudotcp while calling its callbacksPhilip Withnall1-1/+10
This prevents the pseudotcp socket from being destroyed from within a callback.
2014-01-31agent: Always emit a readable callback when pseudo-TCP data arrivesPhilip Withnall1-1/+4
Previously, the pseudo-TCP implementation’s readable() callback would only be invoked when new data was received if it was enabled. The callback is enabled by reading all data from the TCP input buffer until EWOULDBLOCK is returned. Reading all that data is not possible if the client buffer is of a limited size, and can lead to livelocks if the client reads exactly the number of bytes in the TCP input buffer (i.e. its buffer size matches the TCP buffer fill level). Instead, always invoke the readable() callback. This might be slightly less performant, but the whole pseudo-TCP implementation is a shambles anyway, and the callbacks need removing, so why not?