github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/p2pserver/net/netserver/net_utils.go (about)

     1  package netserver
     2  
     3  import (
     4  	"crypto/tls"
     5  	"crypto/x509"
     6  	"errors"
     7  	"io/ioutil"
     8  	"net"
     9  	"strconv"
    10  	"time"
    11  
    12  	"github.com/sixexorg/magnetic-ring/config"
    13  	"github.com/sixexorg/magnetic-ring/log"
    14  	"github.com/sixexorg/magnetic-ring/p2pserver/common"
    15  )
    16  
    17  // createListener creates a net listener on the port
    18  func createListener(port uint16) (net.Listener, error) {
    19  	var listener net.Listener
    20  	var err error
    21  
    22  	isTls := config.GlobalConfig.P2PCfg.IsTLS
    23  	if isTls {
    24  		listener, err = initTlsListen(port)
    25  		if err != nil {
    26  			log.Error("[p2p]initTlslisten failed")
    27  			return nil, errors.New("[p2p]initTlslisten failed")
    28  		}
    29  	} else {
    30  		listener, err = initNonTlsListen(port)
    31  		if err != nil {
    32  			log.Error("[p2p]initNonTlsListen failed")
    33  			return nil, errors.New("[p2p]initNonTlsListen failed")
    34  		}
    35  	}
    36  	return listener, nil
    37  }
    38  
    39  //nonTLSDial return net.Conn with nonTls
    40  func nonTLSDial(addr string) (net.Conn, error) {
    41  	conn, err := net.DialTimeout("tcp", addr, time.Second*common.DIAL_TIMEOUT)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  	return conn, nil
    46  }
    47  
    48  //TLSDial return net.Conn with TLS
    49  func TLSDial(nodeAddr string) (net.Conn, error) {
    50  	CertPath := config.GlobalConfig.P2PCfg.CertPath
    51  	KeyPath := config.GlobalConfig.P2PCfg.KeyPath
    52  	CAPath := config.GlobalConfig.P2PCfg.CAPath
    53  
    54  	clientCertPool := x509.NewCertPool()
    55  
    56  	cacert, err := ioutil.ReadFile(CAPath)
    57  	if err != nil {
    58  		log.Error("[p2p]load CA file fail","err", err)
    59  		return nil, err
    60  	}
    61  	cert, err := tls.LoadX509KeyPair(CertPath, KeyPath)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  
    66  	ret := clientCertPool.AppendCertsFromPEM(cacert)
    67  	if !ret {
    68  		return nil, errors.New("[p2p]failed to parse root certificate")
    69  	}
    70  
    71  	conf := &tls.Config{
    72  		RootCAs:      clientCertPool,
    73  		Certificates: []tls.Certificate{cert},
    74  	}
    75  
    76  	var dialer net.Dialer
    77  	dialer.Timeout = time.Second * common.DIAL_TIMEOUT
    78  	conn, err := tls.DialWithDialer(&dialer, "tcp", nodeAddr, conf)
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  	return conn, nil
    83  }
    84  
    85  //initNonTlsListen return net.Listener with nonTls mode
    86  func initNonTlsListen(port uint16) (net.Listener, error) {
    87  	listener, err := net.Listen("tcp", ":"+strconv.Itoa(int(port)))
    88  	if err != nil {
    89  		log.Error("[p2p]Error listening","err", err.Error())
    90  		return nil, err
    91  	}
    92  	return listener, nil
    93  }
    94  
    95  //initTlsListen return net.Listener with Tls mode
    96  func initTlsListen(port uint16) (net.Listener, error) {
    97  	CertPath := config.GlobalConfig.P2PCfg.CertPath
    98  	KeyPath := config.GlobalConfig.P2PCfg.KeyPath
    99  	CAPath := config.GlobalConfig.P2PCfg.CAPath
   100  
   101  	// load cert
   102  	cert, err := tls.LoadX509KeyPair(CertPath, KeyPath)
   103  	if err != nil {
   104  		log.Error("[p2p]load keys fail","err", err)
   105  		return nil, err
   106  	}
   107  	// load root ca
   108  	caData, err := ioutil.ReadFile(CAPath)
   109  	if err != nil {
   110  		log.Error("[p2p]read ca fail","err", err)
   111  		return nil, err
   112  	}
   113  	pool := x509.NewCertPool()
   114  	ret := pool.AppendCertsFromPEM(caData)
   115  	if !ret {
   116  		return nil, errors.New("[p2p]failed to parse root certificate")
   117  	}
   118  
   119  	tlsConfig := &tls.Config{
   120  		Certificates: []tls.Certificate{cert},
   121  		RootCAs:      pool,
   122  		ClientAuth:   tls.RequireAndVerifyClientCert,
   123  		ClientCAs:    pool,
   124  	}
   125  
   126  	log.Info("[p2p]TLS listen ","port", strconv.Itoa(int(port)))
   127  	listener, err := tls.Listen("tcp", ":"+strconv.Itoa(int(port)), tlsConfig)
   128  	if err != nil {
   129  		log.Error("err","err",err)
   130  		return nil, err
   131  	}
   132  	return listener, nil
   133  }