summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--test/packetimpact/dut/posix_server.cc119
-rw-r--r--test/packetimpact/proto/posix_server.proto87
-rw-r--r--test/packetimpact/testbench/dut.go118
3 files changed, 133 insertions, 191 deletions
diff --git a/test/packetimpact/dut/posix_server.cc b/test/packetimpact/dut/posix_server.cc
index 2ebd3b95b..dc3024f44 100644
--- a/test/packetimpact/dut/posix_server.cc
+++ b/test/packetimpact/dut/posix_server.cc
@@ -174,41 +174,41 @@ class PosixImpl final : public posix_server::Posix::Service {
grpc_impl::ServerContext *context,
const ::posix_server::GetSockOptRequest *request,
::posix_server::GetSockOptResponse *response) override {
- socklen_t optlen = request->optlen();
- std::vector<char> buf(optlen);
- response->set_ret(::getsockopt(request->sockfd(), request->level(),
- request->optname(), buf.data(), &optlen));
- response->set_errno_(errno);
- if (optlen >= 0) {
- response->set_optval(buf.data(), optlen);
+ switch (request->type()) {
+ case ::posix_server::GetSockOptRequest::BYTES: {
+ socklen_t optlen = request->optlen();
+ std::vector<char> buf(optlen);
+ response->set_ret(::getsockopt(request->sockfd(), request->level(),
+ request->optname(), buf.data(),
+ &optlen));
+ if (optlen >= 0) {
+ response->mutable_optval()->set_bytesval(buf.data(), optlen);
+ }
+ break;
+ }
+ case ::posix_server::GetSockOptRequest::INT: {
+ int intval = 0;
+ socklen_t optlen = sizeof(intval);
+ response->set_ret(::getsockopt(request->sockfd(), request->level(),
+ request->optname(), &intval, &optlen));
+ response->mutable_optval()->set_intval(intval);
+ break;
+ }
+ case ::posix_server::GetSockOptRequest::TIME: {
+ timeval tv;
+ socklen_t optlen = sizeof(tv);
+ response->set_ret(::getsockopt(request->sockfd(), request->level(),
+ request->optname(), &tv, &optlen));
+ response->mutable_optval()->mutable_timeval()->set_seconds(tv.tv_sec);
+ response->mutable_optval()->mutable_timeval()->set_microseconds(
+ tv.tv_usec);
+ break;
+ }
+ default:
+ return ::grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
+ "Unknown SockOpt Type");
}
- return ::grpc::Status::OK;
- }
-
- ::grpc::Status GetSockOptInt(
- ::grpc::ServerContext *context,
- const ::posix_server::GetSockOptIntRequest *request,
- ::posix_server::GetSockOptIntResponse *response) override {
- int opt = 0;
- socklen_t optlen = sizeof(opt);
- response->set_ret(::getsockopt(request->sockfd(), request->level(),
- request->optname(), &opt, &optlen));
- response->set_errno_(errno);
- response->set_intval(opt);
- return ::grpc::Status::OK;
- }
-
- ::grpc::Status GetSockOptTimeval(
- ::grpc::ServerContext *context,
- const ::posix_server::GetSockOptTimevalRequest *request,
- ::posix_server::GetSockOptTimevalResponse *response) override {
- timeval tv;
- socklen_t optlen = sizeof(tv);
- response->set_ret(::getsockopt(request->sockfd(), request->level(),
- request->optname(), &tv, &optlen));
response->set_errno_(errno);
- response->mutable_timeval()->set_seconds(tv.tv_sec);
- response->mutable_timeval()->set_microseconds(tv.tv_usec);
return ::grpc::Status::OK;
}
@@ -253,33 +253,32 @@ class PosixImpl final : public posix_server::Posix::Service {
grpc_impl::ServerContext *context,
const ::posix_server::SetSockOptRequest *request,
::posix_server::SetSockOptResponse *response) override {
- response->set_ret(setsockopt(request->sockfd(), request->level(),
- request->optname(), request->optval().c_str(),
- request->optval().size()));
- response->set_errno_(errno);
- return ::grpc::Status::OK;
- }
-
- ::grpc::Status SetSockOptInt(
- ::grpc::ServerContext *context,
- const ::posix_server::SetSockOptIntRequest *request,
- ::posix_server::SetSockOptIntResponse *response) override {
- int opt = request->intval();
- response->set_ret(::setsockopt(request->sockfd(), request->level(),
- request->optname(), &opt, sizeof(opt)));
- response->set_errno_(errno);
- return ::grpc::Status::OK;
- }
-
- ::grpc::Status SetSockOptTimeval(
- ::grpc::ServerContext *context,
- const ::posix_server::SetSockOptTimevalRequest *request,
- ::posix_server::SetSockOptTimevalResponse *response) override {
- timeval tv = {.tv_sec = static_cast<__time_t>(request->timeval().seconds()),
- .tv_usec = static_cast<__suseconds_t>(
- request->timeval().microseconds())};
- response->set_ret(setsockopt(request->sockfd(), request->level(),
- request->optname(), &tv, sizeof(tv)));
+ switch (request->optval().val_case()) {
+ case ::posix_server::SockOptVal::kBytesval:
+ response->set_ret(setsockopt(request->sockfd(), request->level(),
+ request->optname(),
+ request->optval().bytesval().c_str(),
+ request->optval().bytesval().size()));
+ break;
+ case ::posix_server::SockOptVal::kIntval: {
+ int opt = request->optval().intval();
+ response->set_ret(::setsockopt(request->sockfd(), request->level(),
+ request->optname(), &opt, sizeof(opt)));
+ break;
+ }
+ case ::posix_server::SockOptVal::kTimeval: {
+ timeval tv = {.tv_sec = static_cast<__time_t>(
+ request->optval().timeval().seconds()),
+ .tv_usec = static_cast<__suseconds_t>(
+ request->optval().timeval().microseconds())};
+ response->set_ret(setsockopt(request->sockfd(), request->level(),
+ request->optname(), &tv, sizeof(tv)));
+ break;
+ }
+ default:
+ return ::grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
+ "Unknown SockOpt Type");
+ }
response->set_errno_(errno);
return ::grpc::Status::OK;
}
diff --git a/test/packetimpact/proto/posix_server.proto b/test/packetimpact/proto/posix_server.proto
index ab5ba1c85..9dca563f1 100644
--- a/test/packetimpact/proto/posix_server.proto
+++ b/test/packetimpact/proto/posix_server.proto
@@ -42,6 +42,14 @@ message Timeval {
int64 microseconds = 2;
}
+message SockOptVal {
+ oneof val {
+ bytes bytesval = 1;
+ int32 intval = 2;
+ Timeval timeval = 3;
+ }
+}
+
// Request and Response pairs for each Posix service RPC call, sorted.
message AcceptRequest {
@@ -98,36 +106,19 @@ message GetSockOptRequest {
int32 level = 2;
int32 optname = 3;
int32 optlen = 4;
+ enum SockOptType {
+ UNSPECIFIED = 0;
+ BYTES = 1;
+ INT = 2;
+ TIME = 3;
+ }
+ SockOptType type = 5;
}
message GetSockOptResponse {
int32 ret = 1;
int32 errno_ = 2; // "errno" may fail to compile in c++.
- bytes optval = 3;
-}
-
-message GetSockOptIntRequest {
- int32 sockfd = 1;
- int32 level = 2;
- int32 optname = 3;
-}
-
-message GetSockOptIntResponse {
- int32 ret = 1;
- int32 errno_ = 2; // "errno" may fail to compile in c++.
- int32 intval = 3;
-}
-
-message GetSockOptTimevalRequest {
- int32 sockfd = 1;
- int32 level = 2;
- int32 optname = 3;
-}
-
-message GetSockOptTimevalResponse {
- int32 ret = 1;
- int32 errno_ = 2; // "errno" may fail to compile in c++.
- Timeval timeval = 3;
+ SockOptVal optval = 3;
}
message ListenRequest {
@@ -167,7 +158,7 @@ message SetSockOptRequest {
int32 sockfd = 1;
int32 level = 2;
int32 optname = 3;
- bytes optval = 4;
+ SockOptVal optval = 4;
}
message SetSockOptResponse {
@@ -175,30 +166,6 @@ message SetSockOptResponse {
int32 errno_ = 2; // "errno" may fail to compile in c++.
}
-message SetSockOptIntRequest {
- int32 sockfd = 1;
- int32 level = 2;
- int32 optname = 3;
- int32 intval = 4;
-}
-
-message SetSockOptIntResponse {
- int32 ret = 1;
- int32 errno_ = 2;
-}
-
-message SetSockOptTimevalRequest {
- int32 sockfd = 1;
- int32 level = 2;
- int32 optname = 3;
- Timeval timeval = 4;
-}
-
-message SetSockOptTimevalResponse {
- int32 ret = 1;
- int32 errno_ = 2; // "errno" may fail to compile in c++.
-}
-
message SocketRequest {
int32 domain = 1;
int32 type = 2;
@@ -233,32 +200,16 @@ service Posix {
rpc Connect(ConnectRequest) returns (ConnectResponse);
// Call getsockname() on the DUT.
rpc GetSockName(GetSockNameRequest) returns (GetSockNameResponse);
- // Call getsockopt() on the DUT. You should prefer one of the other
- // GetSockOpt* 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
- // sizes or endianness.
+ // Call getsockopt() on the DUT.
rpc GetSockOpt(GetSockOptRequest) returns (GetSockOptResponse);
- // Call getsockopt() on the DUT with an int optval.
- rpc GetSockOptInt(GetSockOptIntRequest) returns (GetSockOptIntResponse);
- // Call getsockopt() on the DUT with a Timeval optval.
- rpc GetSockOptTimeval(GetSockOptTimevalRequest)
- returns (GetSockOptTimevalResponse);
// Call listen() on the DUT.
rpc Listen(ListenRequest) returns (ListenResponse);
// Call send() on the DUT.
rpc Send(SendRequest) returns (SendResponse);
// Call sendto() on the DUT.
rpc SendTo(SendToRequest) returns (SendToResponse);
- // 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
- // sizes or endianness.
+ // Call setsockopt() on the DUT.
rpc SetSockOpt(SetSockOptRequest) returns (SetSockOptResponse);
- // Call setsockopt() on the DUT with an int optval.
- rpc SetSockOptInt(SetSockOptIntRequest) returns (SetSockOptIntResponse);
- // Call setsockopt() on the DUT with a Timeval optval.
- rpc SetSockOptTimeval(SetSockOptTimevalRequest)
- returns (SetSockOptTimevalResponse);
// Call socket() on the DUT.
rpc Socket(SocketRequest) returns (SocketResponse);
// Call recv() on the DUT.
diff --git a/test/packetimpact/testbench/dut.go b/test/packetimpact/testbench/dut.go
index 87eeeeb88..f68d9d62b 100644
--- a/test/packetimpact/testbench/dut.go
+++ b/test/packetimpact/testbench/dut.go
@@ -291,6 +291,26 @@ func (dut *DUT) GetSockNameWithErrno(ctx context.Context, sockfd int32) (int32,
return resp.GetRet(), dut.protoToSockaddr(resp.GetAddr()), syscall.Errno(resp.GetErrno_())
}
+func (dut *DUT) getSockOpt(ctx context.Context, sockfd, level, optname, optlen int32, typ pb.GetSockOptRequest_SockOptType) (int32, *pb.SockOptVal, error) {
+ dut.t.Helper()
+ req := pb.GetSockOptRequest{
+ Sockfd: sockfd,
+ Level: level,
+ Optname: optname,
+ Optlen: optlen,
+ Type: typ,
+ }
+ resp, err := dut.posixServer.GetSockOpt(ctx, &req)
+ if err != nil {
+ dut.t.Fatalf("failed to call GetSockOpt: %s", err)
+ }
+ optval := resp.GetOptval()
+ if optval == nil {
+ dut.t.Fatalf("GetSockOpt response does not contain a value")
+ }
+ return resp.GetRet(), optval, syscall.Errno(resp.GetErrno_())
+}
+
// GetSockOpt calls getsockopt 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 GetSockOptWithErrno. Because endianess and the width of values
@@ -312,17 +332,12 @@ func (dut *DUT) GetSockOpt(sockfd, level, optname, optlen int32) []byte {
// prefer to use a more specific GetSockOptXxxWithErrno function.
func (dut *DUT) GetSockOptWithErrno(ctx context.Context, sockfd, level, optname, optlen int32) (int32, []byte, error) {
dut.t.Helper()
- req := pb.GetSockOptRequest{
- Sockfd: sockfd,
- Level: level,
- Optname: optname,
- Optlen: optlen,
- }
- resp, err := dut.posixServer.GetSockOpt(ctx, &req)
- if err != nil {
- dut.t.Fatalf("failed to call GetSockOpt: %s", err)
+ ret, optval, errno := dut.getSockOpt(ctx, sockfd, level, optname, optlen, pb.GetSockOptRequest_BYTES)
+ bytesval, ok := optval.Val.(*pb.SockOptVal_Bytesval)
+ if !ok {
+ dut.t.Fatalf("GetSockOpt got value type: %T, want bytes", optval)
}
- return resp.GetRet(), resp.GetOptval(), syscall.Errno(resp.GetErrno_())
+ return ret, bytesval.Bytesval, errno
}
// GetSockOptInt calls getsockopt on the DUT and causes a fatal test failure
@@ -342,16 +357,12 @@ func (dut *DUT) GetSockOptInt(sockfd, level, optname int32) int32 {
// GetSockOptIntWithErrno calls getsockopt with an integer optval.
func (dut *DUT) GetSockOptIntWithErrno(ctx context.Context, sockfd, level, optname int32) (int32, int32, error) {
dut.t.Helper()
- req := pb.GetSockOptIntRequest{
- Sockfd: sockfd,
- Level: level,
- Optname: optname,
- }
- resp, err := dut.posixServer.GetSockOptInt(ctx, &req)
- if err != nil {
- dut.t.Fatalf("failed to call GetSockOptInt: %s", err)
+ ret, optval, errno := dut.getSockOpt(ctx, sockfd, level, optname, 0, pb.GetSockOptRequest_INT)
+ intval, ok := optval.Val.(*pb.SockOptVal_Intval)
+ if !ok {
+ dut.t.Fatalf("GetSockOpt got value type: %T, want int", optval)
}
- return resp.GetRet(), resp.GetIntval(), syscall.Errno(resp.GetErrno_())
+ return ret, intval.Intval, errno
}
// GetSockOptTimeval calls getsockopt on the DUT and causes a fatal test failure
@@ -371,20 +382,16 @@ func (dut *DUT) GetSockOptTimeval(sockfd, level, optname int32) unix.Timeval {
// GetSockOptTimevalWithErrno calls getsockopt and returns a timeval.
func (dut *DUT) GetSockOptTimevalWithErrno(ctx context.Context, sockfd, level, optname int32) (int32, unix.Timeval, error) {
dut.t.Helper()
- req := pb.GetSockOptTimevalRequest{
- Sockfd: sockfd,
- Level: level,
- Optname: optname,
- }
- resp, err := dut.posixServer.GetSockOptTimeval(ctx, &req)
- if err != nil {
- dut.t.Fatalf("failed to call GetSockOptTimeval: %s", err)
+ ret, optval, errno := dut.getSockOpt(ctx, sockfd, level, optname, 0, pb.GetSockOptRequest_TIME)
+ tv, ok := optval.Val.(*pb.SockOptVal_Timeval)
+ if !ok {
+ dut.t.Fatalf("GetSockOpt got value type: %T, want timeval", optval)
}
timeval := unix.Timeval{
- Sec: resp.GetTimeval().Seconds,
- Usec: resp.GetTimeval().Microseconds,
+ Sec: tv.Timeval.Seconds,
+ Usec: tv.Timeval.Microseconds,
}
- return resp.GetRet(), timeval, syscall.Errno(resp.GetErrno_())
+ return ret, timeval, errno
}
// Listen calls listen on the DUT and causes a fatal test failure if it doesn't
@@ -473,6 +480,21 @@ func (dut *DUT) SendToWithErrno(ctx context.Context, sockfd int32, buf []byte, f
return resp.GetRet(), syscall.Errno(resp.GetErrno_())
}
+func (dut *DUT) setSockOpt(ctx context.Context, sockfd, level, optname int32, optval *pb.SockOptVal) (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
@@ -493,17 +515,7 @@ func (dut *DUT) SetSockOpt(sockfd, level, optname int32, optval []byte) {
// 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_())
+ return dut.setSockOpt(ctx, sockfd, level, optname, &pb.SockOptVal{Val: &pb.SockOptVal_Bytesval{optval}})
}
// SetSockOptInt calls setsockopt on the DUT and causes a fatal test failure
@@ -522,17 +534,7 @@ func (dut *DUT) SetSockOptInt(sockfd, level, optname, optval int32) {
// SetSockOptIntWithErrno calls setsockopt with an integer optval.
func (dut *DUT) SetSockOptIntWithErrno(ctx context.Context, sockfd, level, optname, optval int32) (int32, error) {
dut.t.Helper()
- req := pb.SetSockOptIntRequest{
- Sockfd: sockfd,
- Level: level,
- Optname: optname,
- Intval: optval,
- }
- resp, err := dut.posixServer.SetSockOptInt(ctx, &req)
- if err != nil {
- dut.t.Fatalf("failed to call SetSockOptInt: %s", err)
- }
- return resp.GetRet(), syscall.Errno(resp.GetErrno_())
+ return dut.setSockOpt(ctx, sockfd, level, optname, &pb.SockOptVal{Val: &pb.SockOptVal_Intval{optval}})
}
// SetSockOptTimeval calls setsockopt on the DUT and causes a fatal test failure
@@ -556,17 +558,7 @@ func (dut *DUT) SetSockOptTimevalWithErrno(ctx context.Context, sockfd, level, o
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_())
+ return dut.setSockOpt(ctx, sockfd, level, optname, &pb.SockOptVal{Val: &pb.SockOptVal_Timeval{&timeval}})
}
// Socket calls socket on the DUT and returns the file descriptor. If socket