mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-01 12:07:31 +01:00
The PSP's getsockopt and setsockopt work like 4.4BSD's, which pspautotests net/inet/options records in detail, and most of it didn't match: flags read back as their bit (SO_REUSEADDR as 4, SO_NBIO as 0x80), buffer sizes have their own defaults, getsockopt copies as much as fits and says how much, and unknown options and levels fail with ENOPROTOOPT and EINVAL. So the socket-level options are now kept in InetSocket, and only the ones that change what the host socket does are passed on to it. That also stops the timeouts reaching the host, where Winsock read the timeval as a millisecond count. Accepted sockets copy their options from the listener, like BSD's sonewconn(). IP_TTL is kept too, as Windows' default is 128 and the PSP's 64. Timeouts are set in microseconds, but kept in 10 ms clock ticks, and one under a tick is no timeout at all (net/inet/limits). Buffers can be up to 233016 bytes (net/inet/limits), 4.4BSD's limit with 256-byte mbufs, where we allowed 8 MB. SO_ERROR reads as an SCE error code rather than an errno (net/inet/tcp). The host's TCP send buffer is capped at 64 KB, closer to the PSP's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
76 lines
2.1 KiB
C++
76 lines
2.1 KiB
C++
#pragma once
|
|
|
|
#include "Common/CommonTypes.h"
|
|
#include "Common/Net/SocketCompat.h"
|
|
|
|
// Keep track of who's using a socket.
|
|
enum class SocketState {
|
|
Unused = 0,
|
|
UsedNetInet,
|
|
UsedProAdhoc,
|
|
};
|
|
|
|
const char *SocketStateToString(SocketState state);
|
|
|
|
// Internal socket state tracking
|
|
struct InetSocket {
|
|
SOCKET sock; // native socket
|
|
SocketState state;
|
|
// NOTE: These are the PSP types. Can be converted to the host types if needed.
|
|
int domain;
|
|
int type;
|
|
int protocol;
|
|
bool nonblocking;
|
|
// SO_RCVTIMEO and SO_SNDTIMEO, for the blocking calls we wait for in emulated time. 0 is forever.
|
|
u32 recvTimeoutUs;
|
|
u32 sendTimeoutUs;
|
|
// The other socket-level options, as the game sees them. Only a few are passed on to the host socket.
|
|
u32 soOptions; // PSP_NET_INET_SO_* flags, like BSD's so_options.
|
|
int lingerTime;
|
|
int sndBuf;
|
|
int rcvBuf;
|
|
int sndLowat;
|
|
int rcvLowat;
|
|
// IP_TTL, kept here since the host's default differs (Windows' is 128, the PSP's 64).
|
|
int ipTtl;
|
|
// The port bind() asked UPnP to forward, removed on close. 0 if none.
|
|
u16 upnpPort;
|
|
// Metadata for debug use only.
|
|
std::string addr;
|
|
int port;
|
|
};
|
|
|
|
// Only use this for sockets whose ID are exposed to the game.
|
|
// Don't really need to bother with the others, as the game doesn't know about them.
|
|
class SocketManager {
|
|
public:
|
|
enum {
|
|
VALID_INET_SOCKET_COUNT = 256,
|
|
MIN_VALID_INET_SOCKET = 1,
|
|
};
|
|
|
|
InetSocket *CreateSocket(int *index, int *returned_errno, SocketState state, int domain, int type, int protocol);
|
|
// for accept()
|
|
InetSocket *AdoptSocket(int *index, SOCKET hostSocket, const InetSocket *derive);
|
|
|
|
bool GetInetSocket(int sock, InetSocket **inetSocket);
|
|
SOCKET GetHostSocketFromInetSocket(int sock);
|
|
bool Close(InetSocket *inetSocket);
|
|
void CloseAll();
|
|
|
|
// For debugger
|
|
const InetSocket *Sockets() {
|
|
return inetSockets_;
|
|
}
|
|
|
|
private:
|
|
int FindFreeSlot();
|
|
|
|
// The last number handed out. Numbers go round-robin from there.
|
|
int lastSlot_ = 0;
|
|
// We use this array from MIN_VALID_INET_SOCKET and forward. It's probably not a good idea to return 0 as a socket.
|
|
InetSocket inetSockets_[VALID_INET_SOCKET_COUNT];
|
|
};
|
|
|
|
extern SocketManager g_socketManager;
|