Sort posix service functions
PiperOrigin-RevId: 305157179
This commit is contained in:
parent
dd98fdd5be
commit
32fc11ee3e
|
@ -61,13 +61,15 @@
|
|||
}
|
||||
|
||||
class PosixImpl final : public posix_server::Posix::Service {
|
||||
::grpc::Status Socket(grpc_impl::ServerContext *context,
|
||||
const ::posix_server::SocketRequest *request,
|
||||
::posix_server::SocketResponse *response) override {
|
||||
response->set_fd(
|
||||
socket(request->domain(), request->type(), request->protocol()));
|
||||
::grpc::Status Accept(grpc_impl::ServerContext *context,
|
||||
const ::posix_server::AcceptRequest *request,
|
||||
::posix_server::AcceptResponse *response) override {
|
||||
sockaddr_storage addr;
|
||||
socklen_t addrlen = sizeof(addr);
|
||||
response->set_fd(accept(request->sockfd(),
|
||||
reinterpret_cast<sockaddr *>(&addr), &addrlen));
|
||||
response->set_errno_(errno);
|
||||
return ::grpc::Status::OK;
|
||||
return sockaddr_to_proto(addr, addrlen, response->mutable_addr());
|
||||
}
|
||||
|
||||
::grpc::Status Bind(grpc_impl::ServerContext *context,
|
||||
|
@ -119,6 +121,14 @@ class PosixImpl final : public posix_server::Posix::Service {
|
|||
return ::grpc::Status::OK;
|
||||
}
|
||||
|
||||
::grpc::Status Close(grpc_impl::ServerContext *context,
|
||||
const ::posix_server::CloseRequest *request,
|
||||
::posix_server::CloseResponse *response) override {
|
||||
response->set_ret(close(request->fd()));
|
||||
response->set_errno_(errno);
|
||||
return ::grpc::Status::OK;
|
||||
}
|
||||
|
||||
::grpc::Status GetSockName(
|
||||
grpc_impl::ServerContext *context,
|
||||
const ::posix_server::GetSockNameRequest *request,
|
||||
|
@ -139,17 +149,6 @@ class PosixImpl final : public posix_server::Posix::Service {
|
|||
return ::grpc::Status::OK;
|
||||
}
|
||||
|
||||
::grpc::Status Accept(grpc_impl::ServerContext *context,
|
||||
const ::posix_server::AcceptRequest *request,
|
||||
::posix_server::AcceptResponse *response) override {
|
||||
sockaddr_storage addr;
|
||||
socklen_t addrlen = sizeof(addr);
|
||||
response->set_fd(accept(request->sockfd(),
|
||||
reinterpret_cast<sockaddr *>(&addr), &addrlen));
|
||||
response->set_errno_(errno);
|
||||
return sockaddr_to_proto(addr, addrlen, response->mutable_addr());
|
||||
}
|
||||
|
||||
::grpc::Status SetSockOpt(
|
||||
grpc_impl::ServerContext *context,
|
||||
const ::posix_server::SetSockOptRequest *request,
|
||||
|
@ -174,10 +173,11 @@ class PosixImpl final : public posix_server::Posix::Service {
|
|||
return ::grpc::Status::OK;
|
||||
}
|
||||
|
||||
::grpc::Status Close(grpc_impl::ServerContext *context,
|
||||
const ::posix_server::CloseRequest *request,
|
||||
::posix_server::CloseResponse *response) override {
|
||||
response->set_ret(close(request->fd()));
|
||||
::grpc::Status Socket(grpc_impl::ServerContext *context,
|
||||
const ::posix_server::SocketRequest *request,
|
||||
::posix_server::SocketResponse *response) override {
|
||||
response->set_fd(
|
||||
socket(request->domain(), request->type(), request->protocol()));
|
||||
response->set_errno_(errno);
|
||||
return ::grpc::Status::OK;
|
||||
}
|
||||
|
|
|
@ -16,17 +16,6 @@ syntax = "proto3";
|
|||
|
||||
package posix_server;
|
||||
|
||||
message SocketRequest {
|
||||
int32 domain = 1;
|
||||
int32 type = 2;
|
||||
int32 protocol = 3;
|
||||
}
|
||||
|
||||
message SocketResponse {
|
||||
int32 fd = 1;
|
||||
int32 errno_ = 2; // "errno" may fail to compile in c++.
|
||||
}
|
||||
|
||||
message SockaddrIn {
|
||||
int32 family = 1;
|
||||
uint32 port = 2;
|
||||
|
@ -48,6 +37,23 @@ message Sockaddr {
|
|||
}
|
||||
}
|
||||
|
||||
message Timeval {
|
||||
int64 seconds = 1;
|
||||
int64 microseconds = 2;
|
||||
}
|
||||
|
||||
// Request and Response pairs for each Posix service RPC call, sorted.
|
||||
|
||||
message AcceptRequest {
|
||||
int32 sockfd = 1;
|
||||
}
|
||||
|
||||
message AcceptResponse {
|
||||
int32 fd = 1;
|
||||
int32 errno_ = 2; // "errno" may fail to compile in c++.
|
||||
Sockaddr addr = 3;
|
||||
}
|
||||
|
||||
message BindRequest {
|
||||
int32 sockfd = 1;
|
||||
Sockaddr addr = 2;
|
||||
|
@ -58,6 +64,15 @@ message BindResponse {
|
|||
int32 errno_ = 2; // "errno" may fail to compile in c++.
|
||||
}
|
||||
|
||||
message CloseRequest {
|
||||
int32 fd = 1;
|
||||
}
|
||||
|
||||
message CloseResponse {
|
||||
int32 ret = 1;
|
||||
int32 errno_ = 2; // "errno" may fail to compile in c++.
|
||||
}
|
||||
|
||||
message GetSockNameRequest {
|
||||
int32 sockfd = 1;
|
||||
}
|
||||
|
@ -78,16 +93,6 @@ message ListenResponse {
|
|||
int32 errno_ = 2; // "errno" may fail to compile in c++.
|
||||
}
|
||||
|
||||
message AcceptRequest {
|
||||
int32 sockfd = 1;
|
||||
}
|
||||
|
||||
message AcceptResponse {
|
||||
int32 fd = 1;
|
||||
int32 errno_ = 2; // "errno" may fail to compile in c++.
|
||||
Sockaddr addr = 3;
|
||||
}
|
||||
|
||||
message SetSockOptRequest {
|
||||
int32 sockfd = 1;
|
||||
int32 level = 2;
|
||||
|
@ -100,11 +105,6 @@ message SetSockOptResponse {
|
|||
int32 errno_ = 2; // "errno" may fail to compile in c++.
|
||||
}
|
||||
|
||||
message Timeval {
|
||||
int64 seconds = 1;
|
||||
int64 microseconds = 2;
|
||||
}
|
||||
|
||||
message SetSockOptTimevalRequest {
|
||||
int32 sockfd = 1;
|
||||
int32 level = 2;
|
||||
|
@ -117,12 +117,14 @@ message SetSockOptTimevalResponse {
|
|||
int32 errno_ = 2; // "errno" may fail to compile in c++.
|
||||
}
|
||||
|
||||
message CloseRequest {
|
||||
int32 fd = 1;
|
||||
message SocketRequest {
|
||||
int32 domain = 1;
|
||||
int32 type = 2;
|
||||
int32 protocol = 3;
|
||||
}
|
||||
|
||||
message CloseResponse {
|
||||
int32 ret = 1;
|
||||
message SocketResponse {
|
||||
int32 fd = 1;
|
||||
int32 errno_ = 2; // "errno" may fail to compile in c++.
|
||||
}
|
||||
|
||||
|
@ -139,16 +141,16 @@ message RecvResponse {
|
|||
}
|
||||
|
||||
service Posix {
|
||||
// Call socket() on the DUT.
|
||||
rpc Socket(SocketRequest) returns (SocketResponse);
|
||||
// Call accept() on the DUT.
|
||||
rpc Accept(AcceptRequest) returns (AcceptResponse);
|
||||
// Call bind() on the DUT.
|
||||
rpc Bind(BindRequest) returns (BindResponse);
|
||||
// Call close() on the DUT.
|
||||
rpc Close(CloseRequest) returns (CloseResponse);
|
||||
// Call getsockname() on the DUT.
|
||||
rpc GetSockName(GetSockNameRequest) returns (GetSockNameResponse);
|
||||
// Call listen() on the DUT.
|
||||
rpc Listen(ListenRequest) returns (ListenResponse);
|
||||
// Call accept() on the DUT.
|
||||
rpc Accept(AcceptRequest) returns (AcceptResponse);
|
||||
// Call setsockopt() on the DUT. You should prefer one of the other
|
||||
// SetSockOpt* functions with a more structured optval or else you may get the
|
||||
// encoding wrong, such as making a bad assumption about the server's word
|
||||
|
@ -157,8 +159,8 @@ service Posix {
|
|||
// Call setsockopt() on the DUT with a Timeval optval.
|
||||
rpc SetSockOptTimeval(SetSockOptTimevalRequest)
|
||||
returns (SetSockOptTimevalResponse);
|
||||
// Call close() on the DUT.
|
||||
rpc Close(CloseRequest) returns (CloseResponse);
|
||||
// Call socket() on the DUT.
|
||||
rpc Socket(SocketRequest) returns (SocketResponse);
|
||||
// Call recv() on the DUT.
|
||||
rpc Recv(RecvRequest) returns (RecvResponse);
|
||||
}
|
||||
|
|
|
@ -65,33 +65,6 @@ func (dut *DUT) TearDown() {
|
|||
dut.conn.Close()
|
||||
}
|
||||
|
||||
// SocketWithErrno calls socket on the DUT and returns the fd and errno.
|
||||
func (dut *DUT) SocketWithErrno(domain, typ, proto int32) (int32, error) {
|
||||
dut.t.Helper()
|
||||
req := pb.SocketRequest{
|
||||
Domain: domain,
|
||||
Type: typ,
|
||||
Protocol: proto,
|
||||
}
|
||||
ctx := context.Background()
|
||||
resp, err := dut.posixServer.Socket(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call Socket: %s", err)
|
||||
}
|
||||
return resp.GetFd(), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
||||
// Socket calls socket on the DUT and returns the file descriptor. If socket
|
||||
// fails on the DUT, the test ends.
|
||||
func (dut *DUT) Socket(domain, typ, proto int32) int32 {
|
||||
dut.t.Helper()
|
||||
fd, err := dut.SocketWithErrno(domain, typ, proto)
|
||||
if fd < 0 {
|
||||
dut.t.Fatalf("failed to create socket: %s", err)
|
||||
}
|
||||
return fd
|
||||
}
|
||||
|
||||
func (dut *DUT) sockaddrToProto(sa unix.Sockaddr) *pb.Sockaddr {
|
||||
dut.t.Helper()
|
||||
switch s := sa.(type) {
|
||||
|
@ -142,236 +115,6 @@ func (dut *DUT) protoToSockaddr(sa *pb.Sockaddr) unix.Sockaddr {
|
|||
return nil
|
||||
}
|
||||
|
||||
// BindWithErrno calls bind on the DUT.
|
||||
func (dut *DUT) BindWithErrno(ctx context.Context, fd int32, sa unix.Sockaddr) (int32, error) {
|
||||
dut.t.Helper()
|
||||
req := pb.BindRequest{
|
||||
Sockfd: fd,
|
||||
Addr: dut.sockaddrToProto(sa),
|
||||
}
|
||||
resp, err := dut.posixServer.Bind(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call Bind: %s", err)
|
||||
}
|
||||
return resp.GetRet(), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
||||
// Bind calls bind on the DUT and causes a fatal test failure if it doesn't
|
||||
// succeed. If more control over the timeout or error handling is
|
||||
// needed, use BindWithErrno.
|
||||
func (dut *DUT) Bind(fd int32, sa unix.Sockaddr) {
|
||||
dut.t.Helper()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *rpcTimeout)
|
||||
defer cancel()
|
||||
ret, err := dut.BindWithErrno(ctx, fd, sa)
|
||||
if ret != 0 {
|
||||
dut.t.Fatalf("failed to bind socket: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// GetSockNameWithErrno calls getsockname on the DUT.
|
||||
func (dut *DUT) GetSockNameWithErrno(ctx context.Context, sockfd int32) (int32, unix.Sockaddr, error) {
|
||||
dut.t.Helper()
|
||||
req := pb.GetSockNameRequest{
|
||||
Sockfd: sockfd,
|
||||
}
|
||||
resp, err := dut.posixServer.GetSockName(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call Bind: %s", err)
|
||||
}
|
||||
return resp.GetRet(), dut.protoToSockaddr(resp.GetAddr()), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
||||
// GetSockName calls getsockname on the DUT and causes a fatal test failure if
|
||||
// it doesn't succeed. If more control over the timeout or error handling is
|
||||
// needed, use GetSockNameWithErrno.
|
||||
func (dut *DUT) GetSockName(sockfd int32) unix.Sockaddr {
|
||||
dut.t.Helper()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *rpcTimeout)
|
||||
defer cancel()
|
||||
ret, sa, err := dut.GetSockNameWithErrno(ctx, sockfd)
|
||||
if ret != 0 {
|
||||
dut.t.Fatalf("failed to getsockname: %s", err)
|
||||
}
|
||||
return sa
|
||||
}
|
||||
|
||||
// ListenWithErrno calls listen on the DUT.
|
||||
func (dut *DUT) ListenWithErrno(ctx context.Context, sockfd, backlog int32) (int32, error) {
|
||||
dut.t.Helper()
|
||||
req := pb.ListenRequest{
|
||||
Sockfd: sockfd,
|
||||
Backlog: backlog,
|
||||
}
|
||||
resp, err := dut.posixServer.Listen(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call Listen: %s", err)
|
||||
}
|
||||
return resp.GetRet(), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
||||
// Listen calls listen on the DUT and causes a fatal test failure if it doesn't
|
||||
// succeed. If more control over the timeout or error handling is needed, use
|
||||
// ListenWithErrno.
|
||||
func (dut *DUT) Listen(sockfd, backlog int32) {
|
||||
dut.t.Helper()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *rpcTimeout)
|
||||
defer cancel()
|
||||
ret, err := dut.ListenWithErrno(ctx, sockfd, backlog)
|
||||
if ret != 0 {
|
||||
dut.t.Fatalf("failed to listen: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// AcceptWithErrno calls accept on the DUT.
|
||||
func (dut *DUT) AcceptWithErrno(ctx context.Context, sockfd int32) (int32, unix.Sockaddr, error) {
|
||||
dut.t.Helper()
|
||||
req := pb.AcceptRequest{
|
||||
Sockfd: sockfd,
|
||||
}
|
||||
resp, err := dut.posixServer.Accept(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call Accept: %s", err)
|
||||
}
|
||||
return resp.GetFd(), dut.protoToSockaddr(resp.GetAddr()), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
||||
// Accept calls accept on the DUT and causes a fatal test failure if it doesn't
|
||||
// succeed. If more control over the timeout or error handling is needed, use
|
||||
// AcceptWithErrno.
|
||||
func (dut *DUT) Accept(sockfd int32) (int32, unix.Sockaddr) {
|
||||
dut.t.Helper()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *rpcTimeout)
|
||||
defer cancel()
|
||||
fd, sa, err := dut.AcceptWithErrno(ctx, sockfd)
|
||||
if fd < 0 {
|
||||
dut.t.Fatalf("failed to accept: %s", err)
|
||||
}
|
||||
return fd, sa
|
||||
}
|
||||
|
||||
// SetSockOptWithErrno calls setsockopt on the DUT. Because endianess and the
|
||||
// width of values might differ between the testbench and DUT architectures,
|
||||
// prefer to use a more specific SetSockOptXxxWithErrno function.
|
||||
func (dut *DUT) SetSockOptWithErrno(ctx context.Context, sockfd, level, optname int32, optval []byte) (int32, error) {
|
||||
dut.t.Helper()
|
||||
req := pb.SetSockOptRequest{
|
||||
Sockfd: sockfd,
|
||||
Level: level,
|
||||
Optname: optname,
|
||||
Optval: optval,
|
||||
}
|
||||
resp, err := dut.posixServer.SetSockOpt(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call SetSockOpt: %s", err)
|
||||
}
|
||||
return resp.GetRet(), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
||||
// SetSockOpt calls setsockopt on the DUT and causes a fatal test failure if it
|
||||
// doesn't succeed. If more control over the timeout or error handling is
|
||||
// needed, use SetSockOptWithErrno. Because endianess and the width of values
|
||||
// might differ between the testbench and DUT architectures, prefer to use a
|
||||
// more specific SetSockOptXxx function.
|
||||
func (dut *DUT) SetSockOpt(sockfd, level, optname int32, optval []byte) {
|
||||
dut.t.Helper()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *rpcTimeout)
|
||||
defer cancel()
|
||||
ret, err := dut.SetSockOptWithErrno(ctx, sockfd, level, optname, optval)
|
||||
if ret != 0 {
|
||||
dut.t.Fatalf("failed to SetSockOpt: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// SetSockOptTimevalWithErrno calls setsockopt with the timeval converted to
|
||||
// bytes.
|
||||
func (dut *DUT) SetSockOptTimevalWithErrno(ctx context.Context, sockfd, level, optname int32, tv *unix.Timeval) (int32, error) {
|
||||
dut.t.Helper()
|
||||
timeval := pb.Timeval{
|
||||
Seconds: int64(tv.Sec),
|
||||
Microseconds: int64(tv.Usec),
|
||||
}
|
||||
req := pb.SetSockOptTimevalRequest{
|
||||
Sockfd: sockfd,
|
||||
Level: level,
|
||||
Optname: optname,
|
||||
Timeval: &timeval,
|
||||
}
|
||||
resp, err := dut.posixServer.SetSockOptTimeval(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call SetSockOptTimeval: %s", err)
|
||||
}
|
||||
return resp.GetRet(), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
||||
// SetSockOptTimeval calls setsockopt on the DUT and causes a fatal test failure
|
||||
// if it doesn't succeed. If more control over the timeout or error handling is
|
||||
// needed, use SetSockOptTimevalWithErrno.
|
||||
func (dut *DUT) SetSockOptTimeval(sockfd, level, optname int32, tv *unix.Timeval) {
|
||||
dut.t.Helper()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *rpcTimeout)
|
||||
defer cancel()
|
||||
ret, err := dut.SetSockOptTimevalWithErrno(ctx, sockfd, level, optname, tv)
|
||||
if ret != 0 {
|
||||
dut.t.Fatalf("failed to SetSockOptTimeval: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// RecvWithErrno calls recv on the DUT.
|
||||
func (dut *DUT) RecvWithErrno(ctx context.Context, sockfd, len, flags int32) (int32, []byte, error) {
|
||||
dut.t.Helper()
|
||||
req := pb.RecvRequest{
|
||||
Sockfd: sockfd,
|
||||
Len: len,
|
||||
Flags: flags,
|
||||
}
|
||||
resp, err := dut.posixServer.Recv(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call Recv: %s", err)
|
||||
}
|
||||
return resp.GetRet(), resp.GetBuf(), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
||||
// Recv calls recv on the DUT and causes a fatal test failure if it doesn't
|
||||
// succeed. If more control over the timeout or error handling is needed, use
|
||||
// RecvWithErrno.
|
||||
func (dut *DUT) Recv(sockfd, len, flags int32) []byte {
|
||||
dut.t.Helper()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *rpcTimeout)
|
||||
defer cancel()
|
||||
ret, buf, err := dut.RecvWithErrno(ctx, sockfd, len, flags)
|
||||
if ret == -1 {
|
||||
dut.t.Fatalf("failed to recv: %s", err)
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
// CloseWithErrno calls close on the DUT.
|
||||
func (dut *DUT) CloseWithErrno(ctx context.Context, fd int32) (int32, error) {
|
||||
dut.t.Helper()
|
||||
req := pb.CloseRequest{
|
||||
Fd: fd,
|
||||
}
|
||||
resp, err := dut.posixServer.Close(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call Close: %s", err)
|
||||
}
|
||||
return resp.GetRet(), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
||||
// Close calls close on the DUT and causes a fatal test failure if it doesn't
|
||||
// succeed. If more control over the timeout or error handling is needed, use
|
||||
// CloseWithErrno.
|
||||
func (dut *DUT) Close(fd int32) {
|
||||
dut.t.Helper()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *rpcTimeout)
|
||||
defer cancel()
|
||||
ret, err := dut.CloseWithErrno(ctx, fd)
|
||||
if ret != 0 {
|
||||
dut.t.Fatalf("failed to close: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// CreateBoundSocket makes a new socket on the DUT, with type typ and protocol
|
||||
// proto, and bound to the IP address addr. Returns the new file descriptor and
|
||||
// the port that was selected on the DUT.
|
||||
|
@ -410,3 +153,263 @@ func (dut *DUT) CreateListener(typ, proto, backlog int32) (int32, uint16) {
|
|||
dut.Listen(fd, backlog)
|
||||
return fd, remotePort
|
||||
}
|
||||
|
||||
// All the functions that make gRPC calls to the Posix service are below, sorted
|
||||
// alphabetically.
|
||||
|
||||
// Accept calls accept on the DUT and causes a fatal test failure if it doesn't
|
||||
// succeed. If more control over the timeout or error handling is needed, use
|
||||
// AcceptWithErrno.
|
||||
func (dut *DUT) Accept(sockfd int32) (int32, unix.Sockaddr) {
|
||||
dut.t.Helper()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *rpcTimeout)
|
||||
defer cancel()
|
||||
fd, sa, err := dut.AcceptWithErrno(ctx, sockfd)
|
||||
if fd < 0 {
|
||||
dut.t.Fatalf("failed to accept: %s", err)
|
||||
}
|
||||
return fd, sa
|
||||
}
|
||||
|
||||
// AcceptWithErrno calls accept on the DUT.
|
||||
func (dut *DUT) AcceptWithErrno(ctx context.Context, sockfd int32) (int32, unix.Sockaddr, error) {
|
||||
dut.t.Helper()
|
||||
req := pb.AcceptRequest{
|
||||
Sockfd: sockfd,
|
||||
}
|
||||
resp, err := dut.posixServer.Accept(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call Accept: %s", err)
|
||||
}
|
||||
return resp.GetFd(), dut.protoToSockaddr(resp.GetAddr()), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
||||
// Bind calls bind on the DUT and causes a fatal test failure if it doesn't
|
||||
// succeed. If more control over the timeout or error handling is
|
||||
// needed, use BindWithErrno.
|
||||
func (dut *DUT) Bind(fd int32, sa unix.Sockaddr) {
|
||||
dut.t.Helper()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *rpcTimeout)
|
||||
defer cancel()
|
||||
ret, err := dut.BindWithErrno(ctx, fd, sa)
|
||||
if ret != 0 {
|
||||
dut.t.Fatalf("failed to bind socket: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// BindWithErrno calls bind on the DUT.
|
||||
func (dut *DUT) BindWithErrno(ctx context.Context, fd int32, sa unix.Sockaddr) (int32, error) {
|
||||
dut.t.Helper()
|
||||
req := pb.BindRequest{
|
||||
Sockfd: fd,
|
||||
Addr: dut.sockaddrToProto(sa),
|
||||
}
|
||||
resp, err := dut.posixServer.Bind(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call Bind: %s", err)
|
||||
}
|
||||
return resp.GetRet(), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
||||
// Close calls close on the DUT and causes a fatal test failure if it doesn't
|
||||
// succeed. If more control over the timeout or error handling is needed, use
|
||||
// CloseWithErrno.
|
||||
func (dut *DUT) Close(fd int32) {
|
||||
dut.t.Helper()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *rpcTimeout)
|
||||
defer cancel()
|
||||
ret, err := dut.CloseWithErrno(ctx, fd)
|
||||
if ret != 0 {
|
||||
dut.t.Fatalf("failed to close: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// CloseWithErrno calls close on the DUT.
|
||||
func (dut *DUT) CloseWithErrno(ctx context.Context, fd int32) (int32, error) {
|
||||
dut.t.Helper()
|
||||
req := pb.CloseRequest{
|
||||
Fd: fd,
|
||||
}
|
||||
resp, err := dut.posixServer.Close(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call Close: %s", err)
|
||||
}
|
||||
return resp.GetRet(), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
||||
// GetSockName calls getsockname on the DUT and causes a fatal test failure if
|
||||
// it doesn't succeed. If more control over the timeout or error handling is
|
||||
// needed, use GetSockNameWithErrno.
|
||||
func (dut *DUT) GetSockName(sockfd int32) unix.Sockaddr {
|
||||
dut.t.Helper()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *rpcTimeout)
|
||||
defer cancel()
|
||||
ret, sa, err := dut.GetSockNameWithErrno(ctx, sockfd)
|
||||
if ret != 0 {
|
||||
dut.t.Fatalf("failed to getsockname: %s", err)
|
||||
}
|
||||
return sa
|
||||
}
|
||||
|
||||
// GetSockNameWithErrno calls getsockname on the DUT.
|
||||
func (dut *DUT) GetSockNameWithErrno(ctx context.Context, sockfd int32) (int32, unix.Sockaddr, error) {
|
||||
dut.t.Helper()
|
||||
req := pb.GetSockNameRequest{
|
||||
Sockfd: sockfd,
|
||||
}
|
||||
resp, err := dut.posixServer.GetSockName(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call Bind: %s", err)
|
||||
}
|
||||
return resp.GetRet(), dut.protoToSockaddr(resp.GetAddr()), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
||||
// Listen calls listen on the DUT and causes a fatal test failure if it doesn't
|
||||
// succeed. If more control over the timeout or error handling is needed, use
|
||||
// ListenWithErrno.
|
||||
func (dut *DUT) Listen(sockfd, backlog int32) {
|
||||
dut.t.Helper()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *rpcTimeout)
|
||||
defer cancel()
|
||||
ret, err := dut.ListenWithErrno(ctx, sockfd, backlog)
|
||||
if ret != 0 {
|
||||
dut.t.Fatalf("failed to listen: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// ListenWithErrno calls listen on the DUT.
|
||||
func (dut *DUT) ListenWithErrno(ctx context.Context, sockfd, backlog int32) (int32, error) {
|
||||
dut.t.Helper()
|
||||
req := pb.ListenRequest{
|
||||
Sockfd: sockfd,
|
||||
Backlog: backlog,
|
||||
}
|
||||
resp, err := dut.posixServer.Listen(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call Listen: %s", err)
|
||||
}
|
||||
return resp.GetRet(), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
||||
// SetSockOpt calls setsockopt on the DUT and causes a fatal test failure if it
|
||||
// doesn't succeed. If more control over the timeout or error handling is
|
||||
// needed, use SetSockOptWithErrno. Because endianess and the width of values
|
||||
// might differ between the testbench and DUT architectures, prefer to use a
|
||||
// more specific SetSockOptXxx function.
|
||||
func (dut *DUT) SetSockOpt(sockfd, level, optname int32, optval []byte) {
|
||||
dut.t.Helper()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *rpcTimeout)
|
||||
defer cancel()
|
||||
ret, err := dut.SetSockOptWithErrno(ctx, sockfd, level, optname, optval)
|
||||
if ret != 0 {
|
||||
dut.t.Fatalf("failed to SetSockOpt: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// SetSockOptWithErrno calls setsockopt on the DUT. Because endianess and the
|
||||
// width of values might differ between the testbench and DUT architectures,
|
||||
// prefer to use a more specific SetSockOptXxxWithErrno function.
|
||||
func (dut *DUT) SetSockOptWithErrno(ctx context.Context, sockfd, level, optname int32, optval []byte) (int32, error) {
|
||||
dut.t.Helper()
|
||||
req := pb.SetSockOptRequest{
|
||||
Sockfd: sockfd,
|
||||
Level: level,
|
||||
Optname: optname,
|
||||
Optval: optval,
|
||||
}
|
||||
resp, err := dut.posixServer.SetSockOpt(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call SetSockOpt: %s", err)
|
||||
}
|
||||
return resp.GetRet(), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
||||
// SetSockOptTimeval calls setsockopt on the DUT and causes a fatal test failure
|
||||
// if it doesn't succeed. If more control over the timeout or error handling is
|
||||
// needed, use SetSockOptTimevalWithErrno.
|
||||
func (dut *DUT) SetSockOptTimeval(sockfd, level, optname int32, tv *unix.Timeval) {
|
||||
dut.t.Helper()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *rpcTimeout)
|
||||
defer cancel()
|
||||
ret, err := dut.SetSockOptTimevalWithErrno(ctx, sockfd, level, optname, tv)
|
||||
if ret != 0 {
|
||||
dut.t.Fatalf("failed to SetSockOptTimeval: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// SetSockOptTimevalWithErrno calls setsockopt with the timeval converted to
|
||||
// bytes.
|
||||
func (dut *DUT) SetSockOptTimevalWithErrno(ctx context.Context, sockfd, level, optname int32, tv *unix.Timeval) (int32, error) {
|
||||
dut.t.Helper()
|
||||
timeval := pb.Timeval{
|
||||
Seconds: int64(tv.Sec),
|
||||
Microseconds: int64(tv.Usec),
|
||||
}
|
||||
req := pb.SetSockOptTimevalRequest{
|
||||
Sockfd: sockfd,
|
||||
Level: level,
|
||||
Optname: optname,
|
||||
Timeval: &timeval,
|
||||
}
|
||||
resp, err := dut.posixServer.SetSockOptTimeval(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call SetSockOptTimeval: %s", err)
|
||||
}
|
||||
return resp.GetRet(), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
||||
// Socket calls socket on the DUT and returns the file descriptor. If socket
|
||||
// fails on the DUT, the test ends.
|
||||
func (dut *DUT) Socket(domain, typ, proto int32) int32 {
|
||||
dut.t.Helper()
|
||||
fd, err := dut.SocketWithErrno(domain, typ, proto)
|
||||
if fd < 0 {
|
||||
dut.t.Fatalf("failed to create socket: %s", err)
|
||||
}
|
||||
return fd
|
||||
}
|
||||
|
||||
// SocketWithErrno calls socket on the DUT and returns the fd and errno.
|
||||
func (dut *DUT) SocketWithErrno(domain, typ, proto int32) (int32, error) {
|
||||
dut.t.Helper()
|
||||
req := pb.SocketRequest{
|
||||
Domain: domain,
|
||||
Type: typ,
|
||||
Protocol: proto,
|
||||
}
|
||||
ctx := context.Background()
|
||||
resp, err := dut.posixServer.Socket(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call Socket: %s", err)
|
||||
}
|
||||
return resp.GetFd(), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
||||
// Recv calls recv on the DUT and causes a fatal test failure if it doesn't
|
||||
// succeed. If more control over the timeout or error handling is needed, use
|
||||
// RecvWithErrno.
|
||||
func (dut *DUT) Recv(sockfd, len, flags int32) []byte {
|
||||
dut.t.Helper()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *rpcTimeout)
|
||||
defer cancel()
|
||||
ret, buf, err := dut.RecvWithErrno(ctx, sockfd, len, flags)
|
||||
if ret == -1 {
|
||||
dut.t.Fatalf("failed to recv: %s", err)
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
// RecvWithErrno calls recv on the DUT.
|
||||
func (dut *DUT) RecvWithErrno(ctx context.Context, sockfd, len, flags int32) (int32, []byte, error) {
|
||||
dut.t.Helper()
|
||||
req := pb.RecvRequest{
|
||||
Sockfd: sockfd,
|
||||
Len: len,
|
||||
Flags: flags,
|
||||
}
|
||||
resp, err := dut.posixServer.Recv(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call Recv: %s", err)
|
||||
}
|
||||
return resp.GetRet(), resp.GetBuf(), syscall.Errno(resp.GetErrno_())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue