github.com/yggdrasil-network/yggdrasil-go@v0.5.6/src/core/link_tls.go (about)

     1  package core
     2  
     3  import (
     4  	"context"
     5  	"crypto/tls"
     6  	"fmt"
     7  	"net"
     8  	"net/url"
     9  
    10  	"github.com/Arceliar/phony"
    11  )
    12  
    13  type linkTLS struct {
    14  	phony.Inbox
    15  	*links
    16  	tcp        *linkTCP
    17  	listener   *net.ListenConfig
    18  	config     *tls.Config
    19  	_listeners map[*Listener]context.CancelFunc
    20  }
    21  
    22  func (l *links) newLinkTLS(tcp *linkTCP) *linkTLS {
    23  	lt := &linkTLS{
    24  		links: l,
    25  		tcp:   tcp,
    26  		listener: &net.ListenConfig{
    27  			Control:   tcp.tcpContext,
    28  			KeepAlive: -1,
    29  		},
    30  		config:     l.core.config.tls.Clone(),
    31  		_listeners: map[*Listener]context.CancelFunc{},
    32  	}
    33  	return lt
    34  }
    35  
    36  func (l *linkTLS) dial(ctx context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) {
    37  	dialers, err := l.tcp.dialersFor(url, info)
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  	if len(dialers) == 0 {
    42  		return nil, nil
    43  	}
    44  	for _, d := range dialers {
    45  		tlsconfig := l.config.Clone()
    46  		tlsconfig.ServerName = options.tlsSNI
    47  		tlsdialer := &tls.Dialer{
    48  			NetDialer: d.dialer,
    49  			Config:    tlsconfig,
    50  		}
    51  		var conn net.Conn
    52  		conn, err = tlsdialer.DialContext(ctx, "tcp", d.addr.String())
    53  		if err != nil {
    54  			continue
    55  		}
    56  		return conn, nil
    57  	}
    58  	return nil, err
    59  }
    60  
    61  func (l *linkTLS) listen(ctx context.Context, url *url.URL, sintf string) (net.Listener, error) {
    62  	hostport := url.Host
    63  	if sintf != "" {
    64  		if host, port, err := net.SplitHostPort(hostport); err == nil {
    65  			hostport = fmt.Sprintf("[%s%%%s]:%s", host, sintf, port)
    66  		}
    67  	}
    68  	listener, err := l.listener.Listen(ctx, "tcp", hostport)
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  	tlslistener := tls.NewListener(listener, l.config)
    73  	return tlslistener, nil
    74  }