<feed xmlns='http://www.w3.org/2005/Atom'>
<title>eglantine-cirakg/src/core/internal_network, branch nx2</title>
<subtitle>Mirror of github.com/cira0100/Eglantine-public nx2, a fork of Djihads80/Eglantine.</subtitle>
<id>https://git.cirakg.xyz/eglantine-cirakg/atom?h=nx2</id>
<link rel='self' href='https://git.cirakg.xyz/eglantine-cirakg/atom?h=nx2'/>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/eglantine-cirakg/'/>
<updated>2026-11-03T00:39:54+00:00</updated>
<entry>
<title>network: close each bsd fd once and drop unwanted or malformed room packets</title>
<updated>2026-11-03T00:39:54+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-11-03T00:39:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/eglantine-cirakg/commit/?id=4304d2704a57c22d5b3f8576b5acebc57a6a7eef'/>
<id>urn:sha1:4304d2704a57c22d5b3f8576b5acebc57a6a7eef</id>
<content type='text'>
Two threads closing the same fd both copied the descriptor and both called
Close(), so a host socket could be closed twice, and the second closesocket
could hit an unrelated socket that had reused the host fd. CloseImpl now
frees the slot under file_descriptors_mutex first and only that thread closes
the socket; the other gets EBADF.

OnProxyPacketReceived decompressed every room packet when any fd had a
socket, including native sockets and proxy sockets on other ports. Sockets
now report through AcceptsProxyPacket whether they want a packet, and only
those are collected, so an unwanted packet is not decompressed.

DecompressDataZSTD passed the frame's declared size straight to the vector
constructor, so a malformed or unsized frame from a room member threw on the
room thread. The new TryDecompressDataZSTD rejects invalid, unsized and
oversized frames, and bsd drops such packets with a warning.
DecompressDataZSTD now returns an empty vector for them instead of throwing.

Assisted-by: Claude Opus 5.5 (investigation and implementation)
</content>
</entry>
<entry>
<title>network: keep fcntl modes across MSG_DONTWAIT and decompress room packets once</title>
<updated>2026-11-03T00:15:29+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-11-03T00:15:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/eglantine-cirakg/commit/?id=d6b32aac3c75a6a0c4190a8b6b2b1fbc5f3e8801'/>
<id>urn:sha1:d6b32aac3c75a6a0c4190a8b6b2b1fbc5f3e8801</id>
<content type='text'>
A receive with MSG_DONTWAIT restored the blocking mode from the descriptor copy taken
before the call. When fcntl(SETFL, O_NONBLOCK) ran during the receive, the fd kept
reporting O_NONBLOCK while its socket blocked again. Receives now switch the mode only
for MSG_DONTWAIT and read the current flags under file_descriptors_mutex at both ends,
and SETFL changes the mode and the stored flags in the same critical section.

OnProxyPacketReceived decompressed each room packet once per matching socket while
holding file_descriptors_mutex, so every bsd call waited for it. It now copies the
distinct sockets under the lock, decompresses once without it and delivers the result.

Also reject fd == MAX_FD in IsFileDescriptorValid and PollImpl, which read past the
table, and guard the ProxySocket blocking and receive timeout setters with
packets_mutex, matching their reader.

Assisted-by: Claude Opus 5.5 (investigation and implementation)
</content>
</entry>
<entry>
<title>network: use the socket type for room stream reads and wake all readers</title>
<updated>2026-11-02T23:28:31+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-11-02T23:28:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/eglantine-cirakg/commit/?id=3e29ad38277195a2930b6ae89dba6d3e698c17e2'/>
<id>urn:sha1:3e29ad38277195a2930b6ae89dba6d3e698c17e2</id>
<content type='text'>
socket(AF_INET, SOCK_STREAM, 0) leaves the protocol unspecified, so the
TCP checks in ProxySocket::Recv and ReceivePacket missed such sockets.
recv() then waited for the timeout and returned EAGAIN instead of end of
stream, and partial reads dropped the rest of the packet. Keep the socket
type and use it for these checks. The protocol stays as it is, because it
is sent to other room members.

A MSG_PEEK reader leaves the packet queued, so notify every waiter when a
packet arrives instead of only one.

Assisted-by: Claude Opus 5.5 (investigation and implementation)
</content>
</entry>
<entry>
<title>network: fix room socket races and share the room network check</title>
<updated>2026-11-02T23:17:34+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-11-02T23:17:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/eglantine-cirakg/commit/?id=78e0a12180a71adf8dffc2c2f6697a0a0735d5ea'/>
<id>urn:sha1:78e0a12180a71adf8dffc2c2f6697a0a0735d5ea</id>
<content type='text'>
bsd:s, bsd:u and bsd:a share one file descriptor table, but each
service bound its own proxy packet callback, so every room packet was
queued three times on each socket. Bind the callback once.

The room thread walked the descriptor table without a lock while bsd
created and closed sockets, so it could reach a destroyed or not yet
created socket. Guard the table with a mutex, and publish a socket only
after it is created and initialized. Check airplane mode before an fd
is taken, so a refused socket no longer leaks its slot.

ProxySocket now initializes protocol, decompresses packets outside the
packet lock without copying the compressed data first, and keeps a read
offset for partial TCP reads instead of erasing from the front.

Add Network::GetRoomIPv4Address(), set only in the Joined and Moderator
states. NIFM uses it for network availability and for every reported
address, including EnumerateNetworkInterfaces and GetCurrentIpAddress,
so no call reports the room address while another rejects the network.

Assisted-by: Claude Opus 5.5 (investigation and implementation)
</content>
</entry>
<entry>
<title>network: fix room host LAN Play and room socket review issues</title>
<updated>2026-11-02T22:40:30+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-11-02T22:40:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/eglantine-cirakg/commit/?id=694bc8df5c8d5b614bdbdbfa43c57a08316f88c2'/>
<id>urn:sha1:694bc8df5c8d5b614bdbdbfa43c57a08316f88c2</id>
<content type='text'>
The room host and room moderators are in the Moderator state, not
Joined, so the airplane mode override for joined rooms did not apply to
them and LAN Play still returned them to the menu. Accept both states.
Share the room address override between the NIFM profile and IP config
calls so they cannot drift apart.

recv() on a room TCP socket now waited for the receive timeout, because
Recv goes through RecvFrom. Room TCP sockets have no peer, so keep the
previous immediate end-of-stream result when nothing is queued.

Close() now drops queued packets and wakes a blocked recv, which then
fails with EBADF. The socket state that the room thread reads when it
queues a packet is now guarded by the packet mutex.

Assisted-by: Claude Opus 5.5 (investigation and implementation)
</content>
</entry>
<entry>
<title>network: fix ProxySocket receive edge cases</title>
<updated>2026-11-02T20:36:20+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-11-02T20:36:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/eglantine-cirakg/commit/?id=ba3e708dbdc6f0e3124500b79bc28aa35763580b'/>
<id>urn:sha1:ba3e708dbdc6f0e3124500b79bc28aa35763580b</id>
<content type='text'>
Routing recv() through RecvFrom made several old RecvFrom problems
reachable from the normal read path:

- A partial TCP read kept zero bytes in front of the unread data.
- A blocking read busy-waited with yield() and reported ETIMEDOUT.
- MSG_PEEK hit the flags == 0 assert.
- A UDP datagram larger than the buffer was dropped with EMSGSIZE.

Wait on a condition variable signalled when a packet arrives, and report
an expired wait as EAGAIN like an SO_RCVTIMEO timeout. Keep the existing
5s cap for sockets without a receive timeout. Allow MSG_PEEK. Truncate
oversized datagrams as BSD recv() does, and keep the unread tail of a
TCP packet for the next read.

Assisted-by: Claude Opus 5.5 (investigation and implementation)
</content>
</entry>
<entry>
<title>network: deliver room datagrams through ProxySocket::Recv</title>
<updated>2026-11-02T20:14:42+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-11-02T20:14:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/eglantine-cirakg/commit/?id=d60c411ebcde5639704df3cebc3f3f50b3757e2e'/>
<id>urn:sha1:d60c411ebcde5639704df3cebc3f3f50b3757e2e</id>
<content type='text'>
When connected to an emulator room every guest socket is a ProxySocket.
Its Recv was a stub that always returned zero bytes, so games that read
UDP replies with recv() never received them. Mario Kart World LAN Play
reads its discovery replies this way, so guests never saw the host's
room in the LAN browser.

Delegate Recv to RecvFrom without an address, so queued room packets,
non-blocking, timeout, peek and truncation behaviour match recvfrom().

Assisted-by: Claude Opus 5.5 (investigation and implementation)
</content>
</entry>
<entry>
<title>[internal_network] Fix WiFi scanner compilation on GCC 15.3.0 (#4279)</title>
<updated>2026-08-21T21:29:24+00:00</updated>
<author>
<name>crueter</name>
<email>crueter@eden-emu.dev</email>
</author>
<published>2026-08-21T21:29:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/eglantine-cirakg/commit/?id=056d11027cd1a1e5a68ad604d0f93104b6c7b8cb'/>
<id>urn:sha1:056d11027cd1a1e5a68ad604d0f93104b6c7b8cb</id>
<content type='text'>
No idea why this didn't show up earlier.

Signed-off-by: crueter &lt;crueter@eden-emu.dev&gt;
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4279
Reviewed-by: CamilleLaVey &lt;camillelavey99@gmail.com&gt;
Reviewed-by: Samuel &lt;lizzie@eden-emu.dev&gt;
</content>
</entry>
<entry>
<title>[meta] Discourage profanity usage (#4239)</title>
<updated>2026-08-09T00:53:16+00:00</updated>
<author>
<name>crueter</name>
<email>crueter@eden-emu.dev</email>
</author>
<published>2026-08-09T00:53:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/eglantine-cirakg/commit/?id=a3d32a18b88ba39c5d5bbf42b7eb0535895acda2'/>
<id>urn:sha1:a3d32a18b88ba39c5d5bbf42b7eb0535895acda2</id>
<content type='text'>
I'm not into millennial humor, personally.

Proactively removed as much profanity as I could grep.

Signed-off-by: crueter &lt;crueter@eden-emu.dev&gt;
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4239
Reviewed-by: MaranBr &lt;maranbr@eden-emu.dev&gt;
Reviewed-by: Samuel &lt;lizzie@eden-emu.dev&gt;
</content>
</entry>
<entry>
<title>[fmt] use {#:x} instead of 0x{:#x} (#4170)</title>
<updated>2026-07-25T19:47:07+00:00</updated>
<author>
<name>lizzie</name>
<email>lizzie@eden-emu.dev</email>
</author>
<published>2026-07-25T19:47:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/eglantine-cirakg/commit/?id=58dee5330566d8948783eb2246ed4e4cde316068'/>
<id>urn:sha1:58dee5330566d8948783eb2246ed4e4cde316068</id>
<content type='text'>
continuation of #309 but applying to even more files than before :)
also makes them lowercase because `0xfafafa` is better as `0XFAFAFA`

Signed-off-by: lizzie &lt;lizzie@eden-emu.dev&gt;
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4170
Reviewed-by: CamilleLaVey &lt;camillelavey99@gmail.com&gt;
Reviewed-by: Maufeat &lt;sahyno1996@gmail.com&gt;
</content>
</entry>
</feed>
