github.com/godevsig/adaptiveservice@v0.9.23/builtinservices.go (about)

     1  package adaptiveservice
     2  
     3  import (
     4  	"io"
     5  	"net"
     6  )
     7  
     8  const (
     9  	// BuiltinPublisher name
    10  	BuiltinPublisher = "builtin"
    11  	// SrvRegistryInfo : service registryInfo
    12  	SrvRegistryInfo = "registryInfo"
    13  	// SrvProviderInfo : service providerInfo
    14  	SrvProviderInfo = "providerInfo"
    15  	// SrvLANRegistry : service LANRegistry
    16  	SrvLANRegistry = "LANRegistry"
    17  	// SrvReverseProxy : service reverseProxy
    18  	SrvReverseProxy = "reverseProxy"
    19  	// SrvServiceLister : service serviceLister
    20  	SrvServiceLister = "serviceLister"
    21  	// SrvIPObserver : service IPObserver
    22  	SrvIPObserver = "IPObserver"
    23  )
    24  
    25  var sharedInfo struct {
    26  	registryAddr string
    27  	providerID   string
    28  }
    29  
    30  // publishRegistryInfoService declares the registry info service,
    31  // from which user can get registry address.
    32  func (s *Server) publishRegistryInfoService() error {
    33  	if len(s.registryAddr) == 0 {
    34  		panic("registry address not specified")
    35  	}
    36  	sharedInfo.registryAddr = s.registryAddr
    37  	knownMsgs := []KnownMessage{(*reqRegistryInfo)(nil)}
    38  	return s.publish(ScopeProcess|ScopeOS, BuiltinPublisher, SrvRegistryInfo, knownMsgs)
    39  }
    40  
    41  // reply with string
    42  type reqRegistryInfo struct{}
    43  
    44  func (msg *reqRegistryInfo) Handle(stream ContextStream) (reply interface{}) {
    45  	return sharedInfo.registryAddr
    46  }
    47  
    48  func discoverRegistryAddr(lg Logger) (addr string, err error) {
    49  	c := NewClient(WithScope(ScopeProcess|ScopeOS), WithLogger(lg)).SetDiscoverTimeout(0)
    50  	conn := <-c.Discover(BuiltinPublisher, SrvRegistryInfo)
    51  	if conn == nil {
    52  		return "", ErrServiceNotFound(BuiltinPublisher, SrvRegistryInfo)
    53  	}
    54  	defer conn.Close()
    55  	err = conn.SendRecv(&reqRegistryInfo{}, &addr)
    56  	return
    57  }
    58  
    59  // publishProviderInfoService declares the provider info service,
    60  // from which user can get provider ID.
    61  func (s *Server) publishProviderInfoService() error {
    62  	if len(s.providerID) == 0 {
    63  		panic("provider ID not specified")
    64  	}
    65  	sharedInfo.providerID = s.providerID
    66  	knownMsgs := []KnownMessage{(*ReqProviderInfo)(nil)}
    67  	return s.publish(ScopeProcess|ScopeOS, BuiltinPublisher, SrvProviderInfo, knownMsgs)
    68  }
    69  
    70  // ReqProviderInfo gets self provider ID, reply with string.
    71  type ReqProviderInfo struct{}
    72  
    73  // Handle handles ReqProviderInfo.
    74  func (msg *ReqProviderInfo) Handle(stream ContextStream) (reply interface{}) {
    75  	return sharedInfo.providerID
    76  }
    77  
    78  func discoverProviderID(lg Logger) (id string, err error) {
    79  	c := NewClient(WithScope(ScopeProcess|ScopeOS), WithLogger(lg)).SetDiscoverTimeout(0)
    80  	conn := <-c.Discover(BuiltinPublisher, SrvProviderInfo)
    81  	if conn == nil {
    82  		return "", ErrServiceNotFound(BuiltinPublisher, SrvProviderInfo)
    83  	}
    84  	defer conn.Close()
    85  	err = conn.SendRecv(&ReqProviderInfo{}, &id)
    86  	return
    87  }
    88  
    89  // publishLANRegistryService declares the LAN registry service,
    90  // which provides service publishing and discovery service in LAN network.
    91  func (s *Server) publishLANRegistryService() error {
    92  	registry, err := s.newLANRegistry()
    93  	if err != nil {
    94  		return err
    95  	}
    96  	s.addCloser(registry)
    97  
    98  	knownMsgs := []KnownMessage{(*queryServiceInLAN)(nil), (*regServiceInLAN)(nil), (*delServiceInLAN)(nil)}
    99  	return s.publish(ScopeProcess|ScopeOS, BuiltinPublisher, SrvLANRegistry,
   100  		knownMsgs,
   101  		OnNewStreamFunc(func(ctx Context) {
   102  			ctx.SetContext(registry)
   103  		}))
   104  }
   105  
   106  // reply with []*ServiceInfo
   107  type queryServiceInLAN struct {
   108  	publisher string
   109  	service   string
   110  }
   111  
   112  func (msg *queryServiceInLAN) Handle(stream ContextStream) (reply interface{}) {
   113  	registry := stream.GetContext().(*registryLAN)
   114  	return registry.queryServiceInLAN(msg.publisher, msg.service)
   115  }
   116  
   117  // reply OK on success or else reply err
   118  type regServiceInLAN struct {
   119  	publisher string
   120  	service   string
   121  	port      string
   122  }
   123  
   124  func (msg *regServiceInLAN) Handle(stream ContextStream) (reply interface{}) {
   125  	registry := stream.GetContext().(*registryLAN)
   126  	registry.registerServiceInLAN(msg.publisher, msg.service, msg.port)
   127  	return OK
   128  }
   129  
   130  // no reply
   131  type delServiceInLAN struct {
   132  	publisher string
   133  	service   string
   134  }
   135  
   136  func (msg *delServiceInLAN) Handle(stream ContextStream) (reply interface{}) {
   137  	registry := stream.GetContext().(*registryLAN)
   138  	registry.deleteServiceInLAN(msg.publisher, msg.service)
   139  	return nil
   140  }
   141  
   142  // publishReverseProxyService declares the reverse proxy service.
   143  func (s *Server) publishReverseProxyService(scope Scope) error {
   144  	knownMsgs := []KnownMessage{(*proxyRegServiceInWAN)(nil)}
   145  	return s.publish(scope, BuiltinPublisher, SrvReverseProxy,
   146  		knownMsgs,
   147  		OnNewStreamFunc(func(ctx Context) {
   148  			ctx.SetContext(s)
   149  		}))
   150  }
   151  
   152  type proxyRegServiceInWAN struct {
   153  	publisher  string
   154  	service    string
   155  	providerID string
   156  }
   157  
   158  func (msg *proxyRegServiceInWAN) Handle(stream ContextStream) (reply interface{}) {
   159  	s := stream.GetContext().(*Server)
   160  	chanServerConn := make(chan net.Conn)
   161  
   162  	onServerConnection := func(netconn Netconn) bool {
   163  		chanServerConn <- netconn.(net.Conn)
   164  		return true
   165  	}
   166  
   167  	reversesvc := &service{
   168  		s:           s,
   169  		fnOnConnect: onServerConnection,
   170  	}
   171  	reversetran, err := reversesvc.newTCPTransport("")
   172  	if err != nil {
   173  		return err
   174  	}
   175  	s.addCloser(reversetran)
   176  	_, port, _ := net.SplitHostPort(reversetran.lnr.Addr().String()) // from [::]:43807
   177  
   178  	var proxytran *streamTransport
   179  	go func() {
   180  		if err := stream.Recv(nil); err != nil {
   181  			s.lg.Debugf("service cmdconn read lost, closing its proxy")
   182  			reversetran.close()
   183  			if proxytran != nil {
   184  				proxytran.close()
   185  			}
   186  		}
   187  	}()
   188  
   189  	onClientConnection := func(netconn Netconn) bool {
   190  		clientConn := netconn.(net.Conn)
   191  		s.lg.Debugf("reverse proxy: starting for client: %s", clientConn.RemoteAddr().String())
   192  		if err := stream.Send(port); err != nil {
   193  			s.lg.Debugf("service cmdconn write lost, closing its proxy")
   194  			reversetran.close()
   195  			proxytran.close()
   196  			clientConn.Close()
   197  			return true
   198  		}
   199  		serverConn := <-chanServerConn
   200  		go func() {
   201  			io.Copy(serverConn, clientConn)
   202  			serverConn.Close()
   203  			s.lg.Debugf("io copy client => server done")
   204  		}()
   205  		go func() {
   206  			clientConn.Write([]byte{0})
   207  			io.Copy(clientConn, serverConn)
   208  			clientConn.Close()
   209  			s.lg.Debugf("io copy server => client done")
   210  		}()
   211  		return true
   212  	}
   213  
   214  	proxysvc := &service{
   215  		publisherName: msg.publisher,
   216  		serviceName:   msg.service,
   217  		providerID:    msg.providerID,
   218  		s:             s,
   219  		scope:         ScopeWAN,
   220  		fnOnConnect:   onClientConnection,
   221  	}
   222  
   223  	proxytran, err = proxysvc.newTCPTransport("")
   224  	if err != nil {
   225  		return err
   226  	}
   227  	s.addCloser(proxytran)
   228  
   229  	return OK
   230  }
   231  
   232  // ListService lists all services in specified scopes matching
   233  // publisher/service name which can be wildcard:
   234  //   "*" matches all
   235  //  "*bar*" matches bar, foobar, or foobarabc
   236  //  "foo*abc*" matches foobarabc, foobarabc123, or fooabc
   237  // The reply is [4][]*ServiceInfo
   238  type ListService struct {
   239  	TargetScope Scope
   240  	Publisher   string
   241  	Service     string
   242  }
   243  
   244  // Handle handles ListService message.
   245  func (msg *ListService) Handle(stream ContextStream) (reply interface{}) {
   246  	s := stream.GetContext().(*Server)
   247  	var scopes [4][]*ServiceInfo
   248  
   249  	if msg.TargetScope&s.scope&ScopeProcess == ScopeProcess {
   250  		scopes[0] = queryServiceProcess(msg.Publisher, msg.Service)
   251  	}
   252  	if msg.TargetScope&s.scope&ScopeOS == ScopeOS {
   253  		scopes[1] = queryServiceOS(msg.Publisher, msg.Service)
   254  	}
   255  	if msg.TargetScope&s.scope&ScopeLAN == ScopeLAN {
   256  		scopes[2] = queryServiceLAN(msg.Publisher, msg.Service, s.lg)
   257  	}
   258  	if msg.TargetScope&s.scope&ScopeWAN == ScopeWAN {
   259  		scopes[3] = queryServiceWAN(s.registryAddr, msg.Publisher, msg.Service, s.lg)
   260  	}
   261  	return scopes
   262  }
   263  
   264  // publishServiceListerService declares the lister service.
   265  func (s *Server) publishServiceListerService(scope Scope) error {
   266  	knownMsgs := []KnownMessage{(*ListService)(nil)}
   267  	return s.publish(scope, BuiltinPublisher, SrvServiceLister,
   268  		knownMsgs,
   269  		OnNewStreamFunc(func(ctx Context) {
   270  			ctx.SetContext(s)
   271  		}))
   272  }
   273  
   274  // GetObservedIP returns the observed IP of the client.
   275  // The reply is string type.
   276  type GetObservedIP struct{}
   277  
   278  // Handle handles GetObservedIP message.
   279  func (msg GetObservedIP) Handle(stream ContextStream) (reply interface{}) {
   280  	netconn := stream.GetNetconn()
   281  	network := netconn.LocalAddr().Network()
   282  	if network == "chan" || network == "unix" {
   283  		return "127.0.0.1"
   284  	}
   285  
   286  	rhost, _, err := net.SplitHostPort(netconn.RemoteAddr().String())
   287  	if err != nil {
   288  		return err
   289  	}
   290  	return rhost
   291  }
   292  
   293  // publishIPObserverService declares the IP observer service.
   294  func (s *Server) publishIPObserverService() error {
   295  	knownMsgs := []KnownMessage{GetObservedIP{}}
   296  	return s.publish(s.scope, BuiltinPublisher, SrvIPObserver, knownMsgs)
   297  }
   298  
   299  func init() {
   300  	RegisterType((*reqRegistryInfo)(nil))
   301  	RegisterType((*ReqProviderInfo)(nil))
   302  	RegisterType((*queryServiceInLAN)(nil))
   303  	RegisterType((*regServiceInLAN)(nil))
   304  	RegisterType((*delServiceInLAN)(nil))
   305  	RegisterType((*proxyRegServiceInWAN)(nil))
   306  	RegisterType((*ListService)(nil))
   307  	RegisterType([4][]*ServiceInfo{})
   308  	RegisterType(GetObservedIP{})
   309  }