Open darkuranium opened 1 year ago
good job! i never try on the windows. if the windows supports BSD sockets API, i think we can port to this. about firefox, you are right. libpeer cannot work with firefox now. In my experience, there is some error in STUN packet. But i don't have time to check it. If I have time I will look into this issue
Windows does in fact use Berkley sockets (from actual Berkley/BSD, in fact — obviously probably modified by Microsoft at various points). They are only a few (trivial) differences:
<sys/*.h>
& friends, the includes are <winsock2.h>
and <ws2tcpip.h>
; likewise, one has to link with the WS2_32
library.WSAStartup()
, and deinitialized with WSACleanup()
. Fortunately, this can be done in peer_{init,deinit}
(or simply by the user, but there is no harm in calling WSAStartup & WSACleanup multiple times, as it's internally reference-counted).close()
, but instead a closesocket()
. Same exact use & signature, just a different name (since Windows sockets are really handles, and not FDs).send()
, recv()
, and friends use [const] char*
arguments instead of [const] void*
, necessitating casts.Other than that, I had to manually implement gettimeofday()
& strndup()
. The former exists in MinGW as-is, but I wanted to eventually support MSVC.
ports.c
is also different in Windows from POSIX, though the Windows implementation should at least in theory be usable in POSIX systems as-is — it's also much simpler! It relies on gethostbyname
, using our own hostname (obtained via gethostname
) as the parameter. As an aside, this also needs linking with iphlpapi
in Windows.
My initial implementation replaced the necessary heads in-place, but I've since moved the compatibility parts into platform/{address,endian,socket,misc}.h
, which is mostly just "forwarding macros"; one exception being gettimeofday()
, strdup()
, and initialization (the latter being a no-op outside of Windows).
I'd like your feedback on what makes the most sense here. I personally think that having this stuff in a separate platform
folder (or, alternatively, platform_*
files) centralizes the platform-specific parts. The only remaining #ifdef
inside the codebase is for handling ports_get_host_addr
in ports.c
.
I've also started working on a web/Emscripten wrapper for libpeer
. Essentially, the idea is to provide the exact same API, but to make use of the browsers' WebRTC APIs internally. That one's progressing a little slowly because there are some API mismatches between the two, plus I've been having trouble with signaling.
Not sure how much interest you would have in this, but it's a necessity for me (it's the whole reason as to why I'm using WebRTC for games instead of pure UDP implementations such as ENet).
There were a few other minor fixups, for example:
make
(in my case, it's ninja
)
make -j4
is replaced with cmake --build .
(cmake then runs whatever build system was generated)make install
is replaced with cmake --build . --target install
__builtin_*
GNU extensions, and since mbedTLS is by default configured with -Werror
...ERROR-CODE
(0x0009
) attributes, which libpeer does not recognize. I've added support for that, mostly by simply having libpeer recognize it, log it as an error, and log its payload (part of which is a human-readable error string).sample
example declared reader_init()
, but used reader_init("./media/")
; that has now been fixed by making the call also have no parameters.A few things I'd like to see for my own use-case (though I understand if some of these might not fit your goals):
struct Address
has an ipv6 field), but others like ports_get_host_addr()
are IPv4-only. Mind, I don't strictly speaking need this at all, it's more one of those "might as well" situations.I'm more than willing to help with all of these (though I won't be able to actually test IPv6 support), but it's your library, so I'd like your comments on this first!
And sorry about the wall of text, I just figured you'd appreciate the feedback, updates, and clarifications.
I'm seeing the long delays in the browser also. It happens when the browser is waiting for all of the ice candidates to come in. My thinking is that there is some logic in the browser that waits for a timeout period for "the right kind of candidate". This makes sense (for example) when there are only ipv6 candidates available (because the browser can see that the offer's candidates are ipv4-only) -- the browser will wait until the timeout period, which makes sense. What makes less sense is when the browser waits even when there are valid/compatible candidates in the offer.
I haven't seen long delays in the browser when using an aiortc (python) peer, for example. There may be a way to tweak the candidates' attributes such that the browser doesn't wait. The other idea is to use "trickle ice" -- this should reduce the connection times in all scenarios. Just thoughts though... :)
Regarding custom signaling, I'm using libpeer with different signaling and it's not a problem. The main discovery for me was that peer_connection.h is basically a simplified WebRTC API.
I'm seeing the long delays in the browser also. It happens when the browser is waiting for all of the ice candidates to come in. My thinking is that there is some logic in the browser that waits for a timeout period for "the right kind of candidate". This makes sense (for example) when there are only ipv6 candidates available (because the browser can see that the offer's candidates are ipv4-only) -- the browser will wait until the timeout period, which makes sense. What makes less sense is when the browser waits even when there are valid/compatible candidates in the offer.
I haven't seen long delays in the browser when using an aiortc (python) peer, for example. There may be a way to tweak the candidates' attributes such that the browser doesn't wait. The other idea is to use "trickle ice" -- this should reduce the connection times in all scenarios. Just thoughts though... :)
Regarding custom signaling, I'm using libpeer with different signaling and it's not a problem. The main discovery for me was that peer_connection.h is basically a simplified WebRTC API.
So, I've made progress in both Firefox & Chrome. I got Firefox working --- see #59!
Chrome, at least with trickle-ICE on seems to be instant when it has no microphone permission ... but takes ages when it does. So it must be something related to that.
@sepfy @richlegrand https://github.com/sepfy/libpeer/pull/60
Hi. I was wondering if there is any interest in adding Windows support. I know libpeer is primarily intended for embedded devices (ESP32, rPi, etc), but I do believe it has potential for other uses.
My own use-case is to use DataChannels for video game networking. (and perhaps at some point: audio for voice chat)
I'm more than willing to contribute towards such an implementation, though I reckon I'll need your help troubleshooting. In fact, I already worked on a port myself, and I believe I have a mostly-working version, though I get the following error:
(that error code corresponds to
MBEDTLS_ERR_SSL_CONN_EOF
)Update: Above issue was in Waterfox (& confirmed with Firefox), but Chrome seems to work — though only after a long delay (connection finally succeeds ~40-50 seconds after page load).
I suspect the difference between WF/FF & Chrome is one between aggressive nomination vs regular (which is the same issue affecting Firefox's non-compliance with ICE-lite, though as far as I can tell, libpeer doesn't advertise itself as ICE-lite?). Firefox, in particular, appears to send a ton of messages with
USE_CANDIDATE
attribute set, which might be an indicator to help out with the problem (at least according to https://github.com/versatica/mediasoup/issues/650).Quick inspection reveals Firefox to send 30 messages with such an attribute, whereas Chrome sends none.
The good news, however, is that Chrome does work — with libpeer running in Windows! So my port was successful after all. I haven't yet tested it, but I've a sneaking suspicion Firefox would fail to work even with libpeer running on a POSIX system.