parent
591ff0e424
commit
4631de620a
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
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)
|
||||
}
|
||||
resp, err := dut.posixServer.GetSockOpt(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call GetSockOpt: %s", err)
|
||||
}
|
||||
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,
|
||||
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)
|
||||
}
|
||||
resp, err := dut.posixServer.GetSockOptInt(ctx, &req)
|
||||
if err != nil {
|
||||
dut.t.Fatalf("failed to call GetSockOptInt: %s", err)
|
||||
}
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue