mirror of
				https://source.quilibrium.com/quilibrium/ceremonyclient.git
				synced 2025-11-04 11:17:28 +00:00 
			
		
		
		
	
		
			
	
	
		
			63 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			63 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package reuseport
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"context"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									ma "github.com/multiformats/go-multiaddr"
							 | 
						||
| 
								 | 
							
									manet "github.com/multiformats/go-multiaddr/net"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Dial dials the given multiaddr, reusing ports we're currently listening on if
							 | 
						||
| 
								 | 
							
								// possible.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Dial attempts to be smart about choosing the source port. For example, If
							 | 
						||
| 
								 | 
							
								// we're dialing a loopback address and we're listening on one or more loopback
							 | 
						||
| 
								 | 
							
								// ports, Dial will randomly choose one of the loopback ports and addresses and
							 | 
						||
| 
								 | 
							
								// reuse it.
							 | 
						||
| 
								 | 
							
								func (t *Transport) Dial(raddr ma.Multiaddr) (manet.Conn, error) {
							 | 
						||
| 
								 | 
							
									return t.DialContext(context.Background(), raddr)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// DialContext is like Dial but takes a context.
							 | 
						||
| 
								 | 
							
								func (t *Transport) DialContext(ctx context.Context, raddr ma.Multiaddr) (manet.Conn, error) {
							 | 
						||
| 
								 | 
							
									network, addr, err := manet.DialArgs(raddr)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return nil, err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									var d *dialer
							 | 
						||
| 
								 | 
							
									switch network {
							 | 
						||
| 
								 | 
							
									case "tcp4":
							 | 
						||
| 
								 | 
							
										d = t.v4.getDialer(network)
							 | 
						||
| 
								 | 
							
									case "tcp6":
							 | 
						||
| 
								 | 
							
										d = t.v6.getDialer(network)
							 | 
						||
| 
								 | 
							
									default:
							 | 
						||
| 
								 | 
							
										return nil, ErrWrongProto
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									conn, err := d.DialContext(ctx, network, addr)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return nil, err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									maconn, err := manet.WrapNetConn(conn)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										conn.Close()
							 | 
						||
| 
								 | 
							
										return nil, err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return maconn, nil
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (n *network) getDialer(network string) *dialer {
							 | 
						||
| 
								 | 
							
									n.mu.RLock()
							 | 
						||
| 
								 | 
							
									d := n.dialer
							 | 
						||
| 
								 | 
							
									n.mu.RUnlock()
							 | 
						||
| 
								 | 
							
									if d == nil {
							 | 
						||
| 
								 | 
							
										n.mu.Lock()
							 | 
						||
| 
								 | 
							
										defer n.mu.Unlock()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if n.dialer == nil {
							 | 
						||
| 
								 | 
							
											n.dialer = newDialer(n.listeners)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										d = n.dialer
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return d
							 | 
						||
| 
								 | 
							
								}
							 |