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 }