Skip to content

Commit f7b9a87

Browse files
committed
[Net] Reject duplicate active binds via object table query
We set SO_REUSEADDR unconditionally so in-process relaunches can reclaim ports stuck in TIME_WAIT, but we need to ensure we still reject two active socket binds to the same port (Darkness II) within the same process.
1 parent 2ea9004 commit f7b9a87

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

src/xenia/kernel/xsocket.cc

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ X_STATUS XSocket::Initialize(AddressFamily af, Type type, Protocol proto) {
112112
}
113113

114114
// Allow port reuse so that in-process relaunches can rebind ports
115-
// immediately without waiting for TIME_WAIT to expire.
115+
// immediately without waiting for TIME_WAIT to expire. Duplicate active
116+
// binds are caught by the object-table check in Bind() instead.
116117
int reuse = 1;
117118
setsockopt(static_cast<int>(native_handle()), SOL_SOCKET, SO_REUSEADDR,
118119
reinterpret_cast<const char*>(&reuse), sizeof(reuse));
@@ -347,6 +348,23 @@ X_STATUS XSocket::Bind(N_XSOCKADDR_IN* name, int name_len) {
347348
asio::ip::address_v4 addr(name->sin_addr);
348349
uint16_t port = name->sin_port;
349350

351+
// Reject duplicate active binds (Xbox 360 behaviour). SO_REUSEADDR is set
352+
// on the OS socket for TIME_WAIT reclaiming, but games expect a second bind
353+
// to the same port to fail with WSAEADDRINUSE. Query the kernel's live
354+
// object table so the check is naturally correct across in-process relaunches
355+
// (Shutdown destroys the old object table).
356+
if (port != 0) {
357+
auto sockets =
358+
kernel_state()->object_table()->GetObjectsByType<XSocket>(kObjectType);
359+
for (auto& s : sockets) {
360+
if (s.get() != this && s->bound_ && s->bound_port_ == port &&
361+
s->type_ == type_) {
362+
last_error_ = 10048; // WSAEADDRINUSE
363+
return X_STATUS_UNSUCCESSFUL;
364+
}
365+
}
366+
}
367+
350368
asio::error_code ec;
351369

352370
if (acceptor_) {

0 commit comments

Comments
 (0)