Initial commit
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
package grpcserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
controlpb "relay/proto/control"
|
||||
)
|
||||
|
||||
type ControlServiceImpl struct {
|
||||
controlpb.UnimplementedControlServiceServer
|
||||
}
|
||||
|
||||
func (s *ControlServiceImpl) RegisterDevice(
|
||||
ctx context.Context,
|
||||
req *controlpb.RegisterRequest,
|
||||
) (*controlpb.RegisterResponse, error) {
|
||||
return &controlpb.RegisterResponse{Success: true}, nil
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package grpcserver
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"log"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/keepalive"
|
||||
|
||||
controlpb "relay/proto/control"
|
||||
tunnelpb "relay/proto/tunnel"
|
||||
)
|
||||
|
||||
func Serve(addr string, tlsCfg *tls.Config) {
|
||||
grpcServer := grpc.NewServer(
|
||||
grpc.Creds(credentials.NewTLS(tlsCfg)),
|
||||
grpc.KeepaliveParams(keepalive.ServerParameters{
|
||||
Time: 30 * time.Second,
|
||||
Timeout: 10 * time.Second,
|
||||
}),
|
||||
)
|
||||
|
||||
tunnelpb.RegisterTunnelServiceServer(grpcServer, &TunnelServiceImpl{})
|
||||
controlpb.RegisterControlServiceServer(grpcServer, &ControlServiceImpl{})
|
||||
|
||||
ln, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println("gRPC listening on", addr)
|
||||
log.Fatal(grpcServer.Serve(ln))
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package grpcserver
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"relay/device"
|
||||
"relay/registry"
|
||||
|
||||
tunnelpb "relay/proto/tunnel"
|
||||
)
|
||||
|
||||
type TunnelServiceImpl struct {
|
||||
tunnelpb.UnimplementedTunnelServiceServer
|
||||
}
|
||||
|
||||
func (s *TunnelServiceImpl) Tunnel(stream tunnelpb.TunnelService_TunnelServer) error {
|
||||
dev := device.NewDevice(stream)
|
||||
log.Println("Device connected")
|
||||
|
||||
defer func() {
|
||||
log.Println("Device disconnected")
|
||||
dev.Close()
|
||||
registry.Global.Mu.Lock()
|
||||
for d, v := range registry.Global.Domains {
|
||||
if v == dev {
|
||||
registry.Global.Domains[d] = nil
|
||||
log.Println("Domain unbound from device:", d)
|
||||
}
|
||||
}
|
||||
registry.Global.Mu.Unlock()
|
||||
}()
|
||||
|
||||
for {
|
||||
frame, err := stream.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch frame.Type {
|
||||
|
||||
// case tunnelpb.FrameType_FRAME_OPEN:
|
||||
// domain := strings.ToLower(string(frame.Payload))
|
||||
// log.Println("BIND request from device for domain:", domain)
|
||||
// registry.Global.Mu.Lock()
|
||||
// if _, ok := registry.Global.Domains[domain]; ok {
|
||||
// registry.Global.Domains[domain] = dev
|
||||
// log.Println("Domain bound to device:", domain)
|
||||
// } else {
|
||||
// log.Println("Bind rejected, domain not registered:", domain)
|
||||
// }
|
||||
// registry.Global.Mu.Unlock()
|
||||
|
||||
case tunnelpb.FrameType_FRAME_BIND_REQUEST:
|
||||
domain := strings.ToLower(string(frame.Payload))
|
||||
log.Println("BIND request from device for domain:", domain)
|
||||
|
||||
registry.Global.Mu.Lock()
|
||||
if _, ok := registry.Global.Domains[domain]; ok {
|
||||
registry.Global.Domains[domain] = dev
|
||||
registry.Global.Mu.Unlock()
|
||||
|
||||
log.Println("Domain bound to device:", domain)
|
||||
dev.SendFrame(&tunnelpb.Frame{
|
||||
Type: tunnelpb.FrameType_FRAME_BIND_OK,
|
||||
Payload: []byte(domain),
|
||||
})
|
||||
} else {
|
||||
registry.Global.Mu.Unlock()
|
||||
|
||||
log.Println("Bind rejected, domain not registered:", domain)
|
||||
dev.SendFrame(&tunnelpb.Frame{
|
||||
Type: tunnelpb.FrameType_FRAME_BIND_REJECTED,
|
||||
Payload: []byte(domain),
|
||||
})
|
||||
}
|
||||
|
||||
case tunnelpb.FrameType_FRAME_DATA:
|
||||
if c, ok := dev.GetClient(frame.StreamId); ok {
|
||||
if _, err := c.Write(frame.Payload); err != nil {
|
||||
dev.RemoveStream(frame.StreamId)
|
||||
}
|
||||
}
|
||||
|
||||
case tunnelpb.FrameType_FRAME_CLOSE:
|
||||
dev.RemoveStream(frame.StreamId)
|
||||
|
||||
case tunnelpb.FrameType_FRAME_PING:
|
||||
dev.SendFrame(&tunnelpb.Frame{
|
||||
Type: tunnelpb.FrameType_FRAME_PONG,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user