gRPC example

This commit is contained in:
Chad Retz 2018-05-23 09:01:39 -05:00
parent f33268f084
commit 05a541532b
6 changed files with 760 additions and 6 deletions

View File

@ -5,4 +5,5 @@ The following examples are in this directory:
* [simpleclient](simpleclient) - A simple Tor client for connecting to the web or other onion services
* [simpleserver](simpleserver) - Hosting simple "hello world" Tor onion service
* [embeddedversion](embeddedversion) - Example showing how to dump the version of Tor embedded in the binary
* [embeddedfileserver](embeddedfileserver) - Example showing a file server using Tor embedded in the binary
* [embeddedfileserver](embeddedfileserver) - Example showing a file server using Tor embedded in the binary
* [grpc](grpc) - Example showing how to use gRPC over Tor

218
examples/grpc/main.go Normal file
View File

@ -0,0 +1,218 @@
package main
import (
"context"
"fmt"
"io"
"log"
"net"
"reflect"
"strings"
"time"
"github.com/cretz/bine/examples/grpc/pb"
"github.com/cretz/bine/tor"
"google.golang.org/grpc"
)
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
func run() error {
log.Printf("Starting Tor")
// We'll give it 5 minutes to run the whole thing (way too much of course, usually about 20 seconds)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
t, err := tor.Start(ctx, nil)
if err != nil {
return err
}
defer t.Close()
log.Printf("Starting onion service, please wait")
server, onionID, err := startServer(ctx, t)
if err != nil {
return err
}
defer server.Stop()
log.Printf("Onion service available at %v.onion", onionID)
log.Printf("Connecting to onion service")
conn, client, err := startClient(ctx, t, onionID+".onion:80")
if err != nil {
return err
}
defer conn.Close()
log.Printf("Doing simple RPC")
resp, err := client.JoinStrings(ctx, &pb.JoinStringsRequest{Strings: []string{"foo", "bar", "baz"}, Delimiter: "-"})
if err != nil {
return err
} else if resp.Joined != "foo-bar-baz" {
return fmt.Errorf("Invalid response: %v", resp.Joined)
}
log.Printf("Doing server-side streaming RPC")
pStream, err := client.ProvideStrings(ctx, &pb.ProvideStringsRequest{Count: 10})
if err != nil {
return err
}
for i := 0; i < 10; i++ {
if resp, err := pStream.Recv(); err != nil {
return err
} else if resp.String_ != fmt.Sprintf("string-%v", i+1) {
return fmt.Errorf("Invalid response: %v", resp.String_)
}
}
if _, err = pStream.Recv(); err != io.EOF {
return fmt.Errorf("Expected EOF, got %v", err)
}
log.Printf("Doing client-side streaming RPC")
rStream, err := client.ReceiveStrings(ctx)
strs := []string{"foo", "bar", "baz"}
for _, str := range strs {
if err := rStream.Send(&pb.ReceiveStringsRequest{String_: str}); err != nil {
return err
}
}
if resp, err := rStream.CloseAndRecv(); err != nil {
return err
} else if !reflect.DeepEqual(resp.Received, strs) {
return fmt.Errorf("Unexpected response: %v", resp.Received)
}
log.Printf("Doing bi-directional streaming RPC")
eStream, err := client.ExchangeStrings(ctx)
for _, str := range strs {
if err := eStream.Send(&pb.ExchangeStringsRequest{String_: str, WantReturn: str == "baz"}); err != nil {
return err
}
}
if resp, err := eStream.Recv(); err != nil {
return err
} else if !reflect.DeepEqual(resp.Received, strs) {
return fmt.Errorf("Unexpected response: %v", resp.Received)
}
err = eStream.Send(&pb.ExchangeStringsRequest{String_: "one"})
if err == nil {
err = eStream.Send(&pb.ExchangeStringsRequest{String_: "two", WantReturn: true})
}
if err == nil {
err = eStream.CloseSend()
}
if err != nil {
return err
}
if resp, err := eStream.Recv(); err != nil {
return err
} else if !reflect.DeepEqual(resp.Received, []string{"one", "two"}) {
return fmt.Errorf("Unexpected response: %v", resp.Received)
}
if _, err = eStream.Recv(); err != io.EOF {
return fmt.Errorf("Expected EOF, got %v", err)
}
log.Printf("All completed successfully, shutting down")
return nil
}
func startServer(ctx context.Context, t *tor.Tor) (server *grpc.Server, onionID string, err error) {
// Wait at most a few minutes to publish the service
listenCtx, listenCancel := context.WithTimeout(ctx, 3*time.Minute)
defer listenCancel()
// Create an onion service to listen on a random local port but show as 80
// We'll do version 3 since it's quicker
onion, err := t.Listen(listenCtx, &tor.ListenConf{Version3: true, RemotePorts: []int{80}})
if err != nil {
return nil, "", err
}
onionID = onion.ID
// Create the grpc server and start it
server = grpc.NewServer()
pb.RegisterSimpleServiceServer(server, simpleService{})
go func() {
if err := server.Serve(onion); err != nil {
log.Printf("Error serving: %v", err)
}
}()
return
}
func startClient(
ctx context.Context, t *tor.Tor, addr string,
) (conn *grpc.ClientConn, client pb.SimpleServiceClient, err error) {
// Wait at most a few minutes to connect to the service
connCtx, connCancel := context.WithTimeout(ctx, 3*time.Minute)
defer connCancel()
// Make the dialer
dialer, err := t.Dialer(connCtx, nil)
if err != nil {
return nil, nil, err
}
// Make the connection
conn, err = grpc.DialContext(connCtx, addr,
grpc.FailOnNonTempDialError(true),
grpc.WithBlock(),
grpc.WithInsecure(),
grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
dialCtx, dialCancel := context.WithTimeout(ctx, timeout)
defer dialCancel()
return dialer.DialContext(dialCtx, "tcp", addr)
}),
)
if err == nil {
client = pb.NewSimpleServiceClient(conn)
}
return
}
type simpleService struct{}
func (simpleService) JoinStrings(ctx context.Context, req *pb.JoinStringsRequest) (*pb.JoinStringsResponse, error) {
return &pb.JoinStringsResponse{Joined: strings.Join(req.Strings, req.Delimiter)}, nil
}
func (simpleService) ProvideStrings(req *pb.ProvideStringsRequest, srv pb.SimpleService_ProvideStringsServer) error {
for i := 0; uint32(i) < req.Count; i++ {
if err := srv.Send(&pb.ProvideStringsResponse{String_: fmt.Sprintf("string-%v", i+1)}); err != nil {
return err
}
}
return nil
}
func (simpleService) ReceiveStrings(srv pb.SimpleService_ReceiveStringsServer) error {
resp := &pb.ReceiveStringsResponse{}
for {
if req, err := srv.Recv(); err == io.EOF {
return srv.SendAndClose(resp)
} else if err != nil {
return err
} else {
resp.Received = append(resp.Received, req.String_)
}
}
}
func (simpleService) ExchangeStrings(srv pb.SimpleService_ExchangeStringsServer) error {
resp := &pb.ExchangeStringsResponse{}
for {
if req, err := srv.Recv(); err == io.EOF {
return srv.Send(resp)
} else if err != nil {
return err
} else {
resp.Received = append(resp.Received, req.String_)
if req.WantReturn {
if err := srv.Send(resp); err != nil {
return err
}
resp = &pb.ExchangeStringsResponse{}
}
}
}
}

View File

@ -0,0 +1,487 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: service.proto
/*
Package pb is a generated protocol buffer package.
It is generated from these files:
service.proto
It has these top-level messages:
JoinStringsRequest
JoinStringsResponse
ProvideStringsRequest
ProvideStringsResponse
ReceiveStringsRequest
ReceiveStringsResponse
ExchangeStringsRequest
ExchangeStringsResponse
*/
package pb
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type JoinStringsRequest struct {
Strings []string `protobuf:"bytes,1,rep,name=strings" json:"strings,omitempty"`
Delimiter string `protobuf:"bytes,2,opt,name=delimiter" json:"delimiter,omitempty"`
}
func (m *JoinStringsRequest) Reset() { *m = JoinStringsRequest{} }
func (m *JoinStringsRequest) String() string { return proto.CompactTextString(m) }
func (*JoinStringsRequest) ProtoMessage() {}
func (*JoinStringsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *JoinStringsRequest) GetStrings() []string {
if m != nil {
return m.Strings
}
return nil
}
func (m *JoinStringsRequest) GetDelimiter() string {
if m != nil {
return m.Delimiter
}
return ""
}
type JoinStringsResponse struct {
Joined string `protobuf:"bytes,1,opt,name=joined" json:"joined,omitempty"`
}
func (m *JoinStringsResponse) Reset() { *m = JoinStringsResponse{} }
func (m *JoinStringsResponse) String() string { return proto.CompactTextString(m) }
func (*JoinStringsResponse) ProtoMessage() {}
func (*JoinStringsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *JoinStringsResponse) GetJoined() string {
if m != nil {
return m.Joined
}
return ""
}
type ProvideStringsRequest struct {
Count uint32 `protobuf:"varint,1,opt,name=count" json:"count,omitempty"`
}
func (m *ProvideStringsRequest) Reset() { *m = ProvideStringsRequest{} }
func (m *ProvideStringsRequest) String() string { return proto.CompactTextString(m) }
func (*ProvideStringsRequest) ProtoMessage() {}
func (*ProvideStringsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (m *ProvideStringsRequest) GetCount() uint32 {
if m != nil {
return m.Count
}
return 0
}
type ProvideStringsResponse struct {
String_ string `protobuf:"bytes,1,opt,name=string" json:"string,omitempty"`
}
func (m *ProvideStringsResponse) Reset() { *m = ProvideStringsResponse{} }
func (m *ProvideStringsResponse) String() string { return proto.CompactTextString(m) }
func (*ProvideStringsResponse) ProtoMessage() {}
func (*ProvideStringsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (m *ProvideStringsResponse) GetString_() string {
if m != nil {
return m.String_
}
return ""
}
type ReceiveStringsRequest struct {
String_ string `protobuf:"bytes,1,opt,name=string" json:"string,omitempty"`
}
func (m *ReceiveStringsRequest) Reset() { *m = ReceiveStringsRequest{} }
func (m *ReceiveStringsRequest) String() string { return proto.CompactTextString(m) }
func (*ReceiveStringsRequest) ProtoMessage() {}
func (*ReceiveStringsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (m *ReceiveStringsRequest) GetString_() string {
if m != nil {
return m.String_
}
return ""
}
type ReceiveStringsResponse struct {
Received []string `protobuf:"bytes,1,rep,name=received" json:"received,omitempty"`
}
func (m *ReceiveStringsResponse) Reset() { *m = ReceiveStringsResponse{} }
func (m *ReceiveStringsResponse) String() string { return proto.CompactTextString(m) }
func (*ReceiveStringsResponse) ProtoMessage() {}
func (*ReceiveStringsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
func (m *ReceiveStringsResponse) GetReceived() []string {
if m != nil {
return m.Received
}
return nil
}
type ExchangeStringsRequest struct {
String_ string `protobuf:"bytes,1,opt,name=string" json:"string,omitempty"`
WantReturn bool `protobuf:"varint,2,opt,name=want_return,json=wantReturn" json:"want_return,omitempty"`
}
func (m *ExchangeStringsRequest) Reset() { *m = ExchangeStringsRequest{} }
func (m *ExchangeStringsRequest) String() string { return proto.CompactTextString(m) }
func (*ExchangeStringsRequest) ProtoMessage() {}
func (*ExchangeStringsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
func (m *ExchangeStringsRequest) GetString_() string {
if m != nil {
return m.String_
}
return ""
}
func (m *ExchangeStringsRequest) GetWantReturn() bool {
if m != nil {
return m.WantReturn
}
return false
}
type ExchangeStringsResponse struct {
Received []string `protobuf:"bytes,1,rep,name=received" json:"received,omitempty"`
}
func (m *ExchangeStringsResponse) Reset() { *m = ExchangeStringsResponse{} }
func (m *ExchangeStringsResponse) String() string { return proto.CompactTextString(m) }
func (*ExchangeStringsResponse) ProtoMessage() {}
func (*ExchangeStringsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
func (m *ExchangeStringsResponse) GetReceived() []string {
if m != nil {
return m.Received
}
return nil
}
func init() {
proto.RegisterType((*JoinStringsRequest)(nil), "pb.JoinStringsRequest")
proto.RegisterType((*JoinStringsResponse)(nil), "pb.JoinStringsResponse")
proto.RegisterType((*ProvideStringsRequest)(nil), "pb.ProvideStringsRequest")
proto.RegisterType((*ProvideStringsResponse)(nil), "pb.ProvideStringsResponse")
proto.RegisterType((*ReceiveStringsRequest)(nil), "pb.ReceiveStringsRequest")
proto.RegisterType((*ReceiveStringsResponse)(nil), "pb.ReceiveStringsResponse")
proto.RegisterType((*ExchangeStringsRequest)(nil), "pb.ExchangeStringsRequest")
proto.RegisterType((*ExchangeStringsResponse)(nil), "pb.ExchangeStringsResponse")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// Client API for SimpleService service
type SimpleServiceClient interface {
JoinStrings(ctx context.Context, in *JoinStringsRequest, opts ...grpc.CallOption) (*JoinStringsResponse, error)
ProvideStrings(ctx context.Context, in *ProvideStringsRequest, opts ...grpc.CallOption) (SimpleService_ProvideStringsClient, error)
ReceiveStrings(ctx context.Context, opts ...grpc.CallOption) (SimpleService_ReceiveStringsClient, error)
ExchangeStrings(ctx context.Context, opts ...grpc.CallOption) (SimpleService_ExchangeStringsClient, error)
}
type simpleServiceClient struct {
cc *grpc.ClientConn
}
func NewSimpleServiceClient(cc *grpc.ClientConn) SimpleServiceClient {
return &simpleServiceClient{cc}
}
func (c *simpleServiceClient) JoinStrings(ctx context.Context, in *JoinStringsRequest, opts ...grpc.CallOption) (*JoinStringsResponse, error) {
out := new(JoinStringsResponse)
err := grpc.Invoke(ctx, "/pb.SimpleService/JoinStrings", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *simpleServiceClient) ProvideStrings(ctx context.Context, in *ProvideStringsRequest, opts ...grpc.CallOption) (SimpleService_ProvideStringsClient, error) {
stream, err := grpc.NewClientStream(ctx, &_SimpleService_serviceDesc.Streams[0], c.cc, "/pb.SimpleService/ProvideStrings", opts...)
if err != nil {
return nil, err
}
x := &simpleServiceProvideStringsClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type SimpleService_ProvideStringsClient interface {
Recv() (*ProvideStringsResponse, error)
grpc.ClientStream
}
type simpleServiceProvideStringsClient struct {
grpc.ClientStream
}
func (x *simpleServiceProvideStringsClient) Recv() (*ProvideStringsResponse, error) {
m := new(ProvideStringsResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *simpleServiceClient) ReceiveStrings(ctx context.Context, opts ...grpc.CallOption) (SimpleService_ReceiveStringsClient, error) {
stream, err := grpc.NewClientStream(ctx, &_SimpleService_serviceDesc.Streams[1], c.cc, "/pb.SimpleService/ReceiveStrings", opts...)
if err != nil {
return nil, err
}
x := &simpleServiceReceiveStringsClient{stream}
return x, nil
}
type SimpleService_ReceiveStringsClient interface {
Send(*ReceiveStringsRequest) error
CloseAndRecv() (*ReceiveStringsResponse, error)
grpc.ClientStream
}
type simpleServiceReceiveStringsClient struct {
grpc.ClientStream
}
func (x *simpleServiceReceiveStringsClient) Send(m *ReceiveStringsRequest) error {
return x.ClientStream.SendMsg(m)
}
func (x *simpleServiceReceiveStringsClient) CloseAndRecv() (*ReceiveStringsResponse, error) {
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
m := new(ReceiveStringsResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *simpleServiceClient) ExchangeStrings(ctx context.Context, opts ...grpc.CallOption) (SimpleService_ExchangeStringsClient, error) {
stream, err := grpc.NewClientStream(ctx, &_SimpleService_serviceDesc.Streams[2], c.cc, "/pb.SimpleService/ExchangeStrings", opts...)
if err != nil {
return nil, err
}
x := &simpleServiceExchangeStringsClient{stream}
return x, nil
}
type SimpleService_ExchangeStringsClient interface {
Send(*ExchangeStringsRequest) error
Recv() (*ExchangeStringsResponse, error)
grpc.ClientStream
}
type simpleServiceExchangeStringsClient struct {
grpc.ClientStream
}
func (x *simpleServiceExchangeStringsClient) Send(m *ExchangeStringsRequest) error {
return x.ClientStream.SendMsg(m)
}
func (x *simpleServiceExchangeStringsClient) Recv() (*ExchangeStringsResponse, error) {
m := new(ExchangeStringsResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
// Server API for SimpleService service
type SimpleServiceServer interface {
JoinStrings(context.Context, *JoinStringsRequest) (*JoinStringsResponse, error)
ProvideStrings(*ProvideStringsRequest, SimpleService_ProvideStringsServer) error
ReceiveStrings(SimpleService_ReceiveStringsServer) error
ExchangeStrings(SimpleService_ExchangeStringsServer) error
}
func RegisterSimpleServiceServer(s *grpc.Server, srv SimpleServiceServer) {
s.RegisterService(&_SimpleService_serviceDesc, srv)
}
func _SimpleService_JoinStrings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(JoinStringsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SimpleServiceServer).JoinStrings(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/pb.SimpleService/JoinStrings",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SimpleServiceServer).JoinStrings(ctx, req.(*JoinStringsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SimpleService_ProvideStrings_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(ProvideStringsRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(SimpleServiceServer).ProvideStrings(m, &simpleServiceProvideStringsServer{stream})
}
type SimpleService_ProvideStringsServer interface {
Send(*ProvideStringsResponse) error
grpc.ServerStream
}
type simpleServiceProvideStringsServer struct {
grpc.ServerStream
}
func (x *simpleServiceProvideStringsServer) Send(m *ProvideStringsResponse) error {
return x.ServerStream.SendMsg(m)
}
func _SimpleService_ReceiveStrings_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(SimpleServiceServer).ReceiveStrings(&simpleServiceReceiveStringsServer{stream})
}
type SimpleService_ReceiveStringsServer interface {
SendAndClose(*ReceiveStringsResponse) error
Recv() (*ReceiveStringsRequest, error)
grpc.ServerStream
}
type simpleServiceReceiveStringsServer struct {
grpc.ServerStream
}
func (x *simpleServiceReceiveStringsServer) SendAndClose(m *ReceiveStringsResponse) error {
return x.ServerStream.SendMsg(m)
}
func (x *simpleServiceReceiveStringsServer) Recv() (*ReceiveStringsRequest, error) {
m := new(ReceiveStringsRequest)
if err := x.ServerStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func _SimpleService_ExchangeStrings_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(SimpleServiceServer).ExchangeStrings(&simpleServiceExchangeStringsServer{stream})
}
type SimpleService_ExchangeStringsServer interface {
Send(*ExchangeStringsResponse) error
Recv() (*ExchangeStringsRequest, error)
grpc.ServerStream
}
type simpleServiceExchangeStringsServer struct {
grpc.ServerStream
}
func (x *simpleServiceExchangeStringsServer) Send(m *ExchangeStringsResponse) error {
return x.ServerStream.SendMsg(m)
}
func (x *simpleServiceExchangeStringsServer) Recv() (*ExchangeStringsRequest, error) {
m := new(ExchangeStringsRequest)
if err := x.ServerStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
var _SimpleService_serviceDesc = grpc.ServiceDesc{
ServiceName: "pb.SimpleService",
HandlerType: (*SimpleServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "JoinStrings",
Handler: _SimpleService_JoinStrings_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "ProvideStrings",
Handler: _SimpleService_ProvideStrings_Handler,
ServerStreams: true,
},
{
StreamName: "ReceiveStrings",
Handler: _SimpleService_ReceiveStrings_Handler,
ClientStreams: true,
},
{
StreamName: "ExchangeStrings",
Handler: _SimpleService_ExchangeStrings_Handler,
ServerStreams: true,
ClientStreams: true,
},
},
Metadata: "service.proto",
}
func init() { proto.RegisterFile("service.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 333 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0x4f, 0x4f, 0x3a, 0x31,
0x14, 0x4c, 0xf9, 0xe5, 0x87, 0xf0, 0x08, 0x9a, 0x54, 0x59, 0xd6, 0xd5, 0x44, 0xd2, 0x13, 0x17,
0x90, 0xf8, 0xe7, 0xea, 0xcd, 0x83, 0xc6, 0x18, 0x2d, 0x1f, 0xc0, 0xc0, 0xee, 0x0b, 0xd6, 0x40,
0xbb, 0xb6, 0x05, 0xfd, 0x62, 0x7e, 0x3f, 0x43, 0xbb, 0x88, 0x2c, 0x35, 0x7a, 0x9c, 0x79, 0xef,
0xcd, 0x34, 0x33, 0x29, 0x34, 0x0d, 0xea, 0x85, 0x48, 0xb1, 0x9f, 0x6b, 0x65, 0x15, 0xad, 0xe4,
0x63, 0x76, 0x07, 0xf4, 0x56, 0x09, 0x39, 0xb4, 0x5a, 0xc8, 0x89, 0xe1, 0xf8, 0x3a, 0x47, 0x63,
0x69, 0x0c, 0x3b, 0xc6, 0x33, 0x31, 0xe9, 0xfc, 0xeb, 0xd6, 0xf9, 0x0a, 0xd2, 0x63, 0xa8, 0x67,
0x38, 0x15, 0x33, 0x61, 0x51, 0xc7, 0x95, 0x0e, 0xe9, 0xd6, 0xf9, 0x9a, 0x60, 0x3d, 0xd8, 0xdf,
0x50, 0x33, 0xb9, 0x92, 0x06, 0x69, 0x04, 0xd5, 0x17, 0x25, 0x24, 0x66, 0x31, 0x71, 0x17, 0x05,
0x62, 0x3d, 0x68, 0x3d, 0x68, 0xb5, 0x10, 0x19, 0x96, 0xfc, 0x0f, 0xe0, 0x7f, 0xaa, 0xe6, 0xd2,
0xba, 0xfd, 0x26, 0xf7, 0x80, 0x0d, 0x20, 0x2a, 0xaf, 0xaf, 0x0d, 0xfc, 0x03, 0x57, 0x06, 0x1e,
0xb1, 0x53, 0x68, 0x71, 0x4c, 0x51, 0x2c, 0xca, 0x06, 0x3f, 0x1d, 0x5c, 0x40, 0x54, 0x3e, 0x28,
0x2c, 0x12, 0xa8, 0x69, 0x3f, 0xc9, 0x8a, 0x4c, 0xbe, 0x30, 0x7b, 0x84, 0xe8, 0xfa, 0x3d, 0x7d,
0x1e, 0xc9, 0xc9, 0x1f, 0x7d, 0xe8, 0x09, 0x34, 0xde, 0x46, 0xd2, 0x3e, 0x69, 0xb4, 0x73, 0x2d,
0x5d, 0x90, 0x35, 0x0e, 0x4b, 0x8a, 0x3b, 0x86, 0x5d, 0x42, 0x7b, 0x4b, 0xf2, 0xf7, 0x97, 0x9c,
0x7d, 0x54, 0xa0, 0x39, 0x14, 0xb3, 0x7c, 0x8a, 0x43, 0x5f, 0x35, 0xbd, 0x82, 0xc6, 0xb7, 0x4a,
0x68, 0xd4, 0xcf, 0xc7, 0xfd, 0xed, 0xc6, 0x93, 0xf6, 0x16, 0x5f, 0xb8, 0xdd, 0xc0, 0xee, 0x66,
0xe8, 0xf4, 0x70, 0xb9, 0x1a, 0xec, 0x2d, 0x49, 0x42, 0x23, 0x2f, 0x34, 0x20, 0x4b, 0xa9, 0xcd,
0x70, 0xbd, 0x54, 0xb0, 0x21, 0x2f, 0x15, 0xee, 0xa2, 0x4b, 0xe8, 0x3d, 0xec, 0x95, 0xe2, 0xa1,
0xee, 0x20, 0x5c, 0x43, 0x72, 0x14, 0x9c, 0xad, 0xd4, 0x06, 0x64, 0x5c, 0x75, 0x3f, 0xe2, 0xfc,
0x33, 0x00, 0x00, 0xff, 0xff, 0xb0, 0x5e, 0xf9, 0x7a, 0x22, 0x03, 0x00, 0x00,
}

View File

@ -0,0 +1,48 @@
/*
To regen, with `protoc` on the `PATH` and `protoc-gen-go` on the `PATH` (usually via `$GOPATH/bin`), from this dir run:
protoc --go_out=plugins=grpc:. service.proto
*/
syntax = "proto3";
package pb;
service SimpleService {
rpc JoinStrings(JoinStringsRequest) returns (JoinStringsResponse);
rpc ProvideStrings(ProvideStringsRequest) returns (stream ProvideStringsResponse);
rpc ReceiveStrings(stream ReceiveStringsRequest) returns (ReceiveStringsResponse);
rpc ExchangeStrings(stream ExchangeStringsRequest) returns (stream ExchangeStringsResponse);
}
message JoinStringsRequest {
repeated string strings = 1;
string delimiter = 2;
}
message JoinStringsResponse {
string joined = 1;
}
message ProvideStringsRequest {
uint32 count = 1;
}
message ProvideStringsResponse {
string string = 1;
}
message ReceiveStringsRequest {
string string = 1;
}
message ReceiveStringsResponse {
repeated string received = 1;
}
message ExchangeStringsRequest {
string string = 1;
bool want_return = 2;
}
message ExchangeStringsResponse {
repeated string received = 1;
}

View File

@ -73,7 +73,7 @@ type ListenConf struct {
// Version3 determines whether, when Key is nil, a version 2 or version 3
// service/key will be generated. If true it is version 3 (an ed25519 key
// and v3 onion service) and if false it is version 2 (a RSA-2014 key and v2
// and v3 onion service) and if false it is version 2 (a RSA-1024 key and v2
// onion service). If Key is not nil, this value is ignored.
Version3 bool
@ -106,9 +106,9 @@ type ListenConf struct {
// false, the stream is simply not connected but the circuit stays open.
MaxStreamsCloseCircuit bool
// NoWait if true will not wait until the onion service is built. If false,
// the network will be enabled if it's not and then we will wait until
// the onion service is built.
// NoWait if true will not wait until the onion service is published. If
// false, the network will be enabled if it's not and then we will wait
// until the onion service is published.
NoWait bool
}

View File

@ -92,7 +92,7 @@ type StartConf struct {
// started.
ExtraArgs []string
// TorrcFile is the torrc file to on start. If empty, a blank torrc is
// TorrcFile is the torrc file to set on start. If empty, a blank torrc is
// created in the data directory and is used instead.
TorrcFile string