github.com/la5nta/wl2k-go@v0.11.8/transport/dial.go (about) 1 // Copyright 2016 Martin Hebnes Pedersen (LA5NTA). All rights reserved. 2 // Use of this source code is governed by the MIT-license that can be 3 // found in the LICENSE file. 4 5 package transport 6 7 import ( 8 "context" 9 "errors" 10 "net" 11 "sync" 12 ) 13 14 var ( 15 ErrInvalidTarget = errors.New("Invalid or missing target callsign") 16 ErrDigisUnsupported = errors.New("Digipeater path is not supported by this scheme") 17 ErrMissingDialer = errors.New("No dialer has been registered for this scheme") 18 ErrUnsupportedScheme = errors.New("Unsupported URL scheme") 19 ) 20 21 // noCtxDialer wraps a Dialer to implement the ContextDialer interface. 22 type noCtxDialer struct{ Dialer } 23 24 func (d noCtxDialer) DialURLContext(_ context.Context, url *URL) (net.Conn, error) { 25 return d.DialURL(url) 26 } 27 28 // DialURL calls the url.Scheme's Dialer. 29 // 30 // If the URL's scheme is not registered, ErrMissingDialer is returned. 31 func DialURL(url *URL) (net.Conn, error) { 32 return DialURLContext(context.Background(), url) 33 } 34 35 // DialURLContext calls the url.Scheme's ContextDialer. 36 // 37 // If the URL's scheme is not registered, ErrMissingDialer is returned. 38 func DialURLContext(ctx context.Context, url *URL) (net.Conn, error) { 39 dialers.mu.Lock() 40 dialer, ok := dialers.m[url.Scheme] 41 dialers.mu.Unlock() 42 if !ok { 43 return nil, ErrMissingDialer 44 } 45 return dialer.DialURLContext(ctx, url) 46 } 47 48 var dialers struct { 49 mu sync.Mutex 50 m map[string]ContextDialer 51 } 52 53 // RegisterContextDialer registers a new scheme and it's ContextDialer. 54 // 55 // The list of registered dialers is used by DialURL and DialURLContext. 56 func RegisterContextDialer(scheme string, dialer ContextDialer) { 57 dialers.mu.Lock() 58 59 if dialers.m == nil { 60 dialers.m = make(map[string]ContextDialer) 61 } 62 63 dialers.m[scheme] = dialer 64 65 dialers.mu.Unlock() 66 } 67 68 // RigisterDialer registers a new scheme and it's Dialer. 69 // 70 // The list of registered dialers is used by DialURL and DialURLContext. 71 func RegisterDialer(scheme string, dialer Dialer) { 72 d, ok := dialer.(ContextDialer) 73 if !ok { 74 d = noCtxDialer{dialer} 75 } 76 RegisterContextDialer(scheme, d) 77 } 78 79 // UnregisterDialer removes the given scheme's dialer from the list of dialers. 80 func UnregisterDialer(scheme string) { 81 dialers.mu.Lock() 82 delete(dialers.m, scheme) 83 dialers.mu.Unlock() 84 }