base: Abstract the AF_INET-ness out of ListenSocket.
Put them into a subclass called ListenSocketInet. Change-Id: I035621463a7f799c1d36a500ed933dc056238e5e Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69163 Maintainer: Bobby Bruce <bbruce@ucdavis.edu> Maintainer: Gabe Black <gabeblack@google.com> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Jui-min Lee <fcrh@google.com> Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
This commit is contained in:
@@ -173,11 +173,7 @@ ListenSocket::acceptCloexec(int sockfd, struct sockaddr *addr,
|
||||
//
|
||||
//
|
||||
|
||||
ListenSocket::ListenSocket(const std::string &_name, int port)
|
||||
: Named(_name), listening(false), fd(-1), _port(port)
|
||||
{}
|
||||
|
||||
ListenSocket::ListenSocket() : ListenSocket("<unnammed>", -1) {}
|
||||
ListenSocket::ListenSocket(const std::string &_name) : Named(_name) {}
|
||||
|
||||
ListenSocket::~ListenSocket()
|
||||
{
|
||||
@@ -185,9 +181,41 @@ ListenSocket::~ListenSocket()
|
||||
close(fd);
|
||||
}
|
||||
|
||||
// Open a connection. Accept will block, so if you don't want it to,
|
||||
// make sure a connection is ready before you call accept.
|
||||
int
|
||||
ListenSocket::accept()
|
||||
{
|
||||
struct sockaddr_in sockaddr;
|
||||
socklen_t slen = sizeof (sockaddr);
|
||||
int sfd = acceptCloexec(fd, (struct sockaddr *)&sockaddr, &slen);
|
||||
if (sfd == -1)
|
||||
return -1;
|
||||
|
||||
return sfd;
|
||||
}
|
||||
|
||||
ListenSocketInet::ListenSocketInet(const std::string &_name, int port)
|
||||
: ListenSocket(_name), _port(port)
|
||||
{}
|
||||
|
||||
int
|
||||
ListenSocketInet::accept()
|
||||
{
|
||||
int sfd = ListenSocket::accept();
|
||||
if (sfd == -1)
|
||||
return -1;
|
||||
|
||||
int i = 1;
|
||||
int ret = ::setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(i));
|
||||
warn_if(ret < 0, "ListenSocket(accept): setsockopt() TCP_NODELAY failed!");
|
||||
|
||||
return sfd;
|
||||
}
|
||||
|
||||
// Create a socket and configure it for listening
|
||||
bool
|
||||
ListenSocket::listen(int port)
|
||||
ListenSocketInet::listen(int port)
|
||||
{
|
||||
panic_if(listening, "Socket already listening!");
|
||||
|
||||
@@ -228,13 +256,12 @@ ListenSocket::listen(int port)
|
||||
return false;
|
||||
}
|
||||
|
||||
listening = true;
|
||||
anyListening = true;
|
||||
setListening();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ListenSocket::listen()
|
||||
ListenSocketInet::listen()
|
||||
{
|
||||
while (!listen(_port)) {
|
||||
_port++;
|
||||
@@ -245,35 +272,16 @@ ListenSocket::listen()
|
||||
}
|
||||
|
||||
void
|
||||
ListenSocket::output(std::ostream &os) const
|
||||
ListenSocketInet::output(std::ostream &os) const
|
||||
{
|
||||
os << "port " << _port;
|
||||
}
|
||||
|
||||
|
||||
// Open a connection. Accept will block, so if you don't want it to,
|
||||
// make sure a connection is ready before you call accept.
|
||||
int
|
||||
ListenSocket::accept()
|
||||
{
|
||||
struct sockaddr_in sockaddr;
|
||||
socklen_t slen = sizeof (sockaddr);
|
||||
int sfd = acceptCloexec(fd, (struct sockaddr *)&sockaddr, &slen);
|
||||
if (sfd == -1)
|
||||
return -1;
|
||||
|
||||
int i = 1;
|
||||
int ret = ::setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(i));
|
||||
warn_if(ret < 0, "ListenSocket(accept): setsockopt() TCP_NODELAY failed!");
|
||||
|
||||
return sfd;
|
||||
}
|
||||
|
||||
ListenSocketConfig
|
||||
listenSocketInetConfig(int port)
|
||||
{
|
||||
return ListenSocketConfig([port](const std::string &name) {
|
||||
return std::make_unique<ListenSocket>(name, port);
|
||||
return std::make_unique<ListenSocketInet>(name, port);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -93,31 +93,34 @@ class ListenSocket : public Named
|
||||
static void loopbackOnly();
|
||||
|
||||
protected:
|
||||
bool listening;
|
||||
int fd;
|
||||
int _port;
|
||||
bool listening = false;
|
||||
int fd = -1;
|
||||
|
||||
void
|
||||
setListening()
|
||||
{
|
||||
listening = true;
|
||||
anyListening = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* cleanup resets the static variables back to their default values.
|
||||
*/
|
||||
static void cleanup();
|
||||
|
||||
virtual bool listen(int port);
|
||||
ListenSocket(const std::string &_name);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @ingroup api_socket
|
||||
* @{
|
||||
*/
|
||||
ListenSocket(const std::string &_name, int port);
|
||||
ListenSocket();
|
||||
virtual ~ListenSocket();
|
||||
|
||||
virtual int accept();
|
||||
virtual void listen() = 0;
|
||||
|
||||
virtual void listen();
|
||||
|
||||
virtual void output(std::ostream &os) const;
|
||||
virtual void output(std::ostream &os) const = 0;
|
||||
|
||||
int getfd() const { return fd; }
|
||||
bool islistening() const { return listening; }
|
||||
@@ -130,6 +133,13 @@ class ListenSocket : public Named
|
||||
/** @} */ // end of api_socket
|
||||
};
|
||||
|
||||
inline static std::ostream &
|
||||
operator << (std::ostream &os, const ListenSocket &socket)
|
||||
{
|
||||
socket.output(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
using ListenSocketPtr = std::unique_ptr<ListenSocket>;
|
||||
|
||||
class ListenSocketConfig
|
||||
@@ -155,14 +165,24 @@ class ListenSocketConfig
|
||||
|
||||
static inline ListenSocketConfig listenSocketEmptyConfig() { return {}; }
|
||||
|
||||
ListenSocketConfig listenSocketInetConfig(int port);
|
||||
// AF_INET based sockets.
|
||||
|
||||
inline static std::ostream &
|
||||
operator << (std::ostream &os, const ListenSocket &socket)
|
||||
class ListenSocketInet : public ListenSocket
|
||||
{
|
||||
socket.output(os);
|
||||
return os;
|
||||
}
|
||||
protected:
|
||||
int _port;
|
||||
|
||||
virtual bool listen(int port);
|
||||
|
||||
public:
|
||||
ListenSocketInet(const std::string &_name, int port);
|
||||
|
||||
int accept() override;
|
||||
void listen() override;
|
||||
void output(std::ostream &os) const override;
|
||||
};
|
||||
|
||||
ListenSocketConfig listenSocketInetConfig(int port);
|
||||
|
||||
} // namespace gem5
|
||||
|
||||
|
||||
@@ -118,10 +118,10 @@ TEST(UnixSocketAddrTest, TruncatedFileBasedSocket)
|
||||
EXPECT_EQ(truncated_addr, sock_addr.formattedPath);
|
||||
}
|
||||
|
||||
class MockListenSocket : public ListenSocket
|
||||
class MockListenSocket : public ListenSocketInet
|
||||
{
|
||||
public:
|
||||
MockListenSocket(int port) : ListenSocket("mock", port) {}
|
||||
MockListenSocket(int port) : ListenSocketInet("mock", port) {}
|
||||
/*
|
||||
* This mock Listen Socket is used to ensure the static variables are reset
|
||||
* back to their default values after deconstruction (i.e., after a test
|
||||
|
||||
Reference in New Issue
Block a user