| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- package tlstypes
-
- import (
- "container/ring"
- "context"
- "crypto/tls"
- "crypto/x509"
- "errors"
- "fmt"
- "net"
- "strconv"
- "time"
-
- "go.uber.org/zap"
-
- "github.com/9seconds/mtg/config"
- )
-
- const (
- connectionServerKeepCertificates = 5
- connectionServerUpdateEvery = 10 * time.Minute
- )
-
- type connectionServer struct {
- nextWriteItem *ring.Ring
- nextReadItem *ring.Ring
-
- ctx context.Context
- channelGet chan chan<- *x509.Certificate
- }
-
- func (c *connectionServer) fetch() (*x509.Certificate, error) {
- addr := net.JoinHostPort(config.C.CloakHost, strconv.Itoa(config.C.CloakPort))
- conn, err := tls.Dial("tcp", addr, &tls.Config{InsecureSkipVerify: true}) // nolint: gosec
-
- if err != nil {
- return nil, fmt.Errorf("cannot connect to the masked host: %w", err)
- }
-
- defer conn.Close()
-
- if err = conn.Handshake(); err != nil {
- return nil, fmt.Errorf("cannot perform tls handshake: %w", err)
- }
-
- certificates := conn.ConnectionState().PeerCertificates
- if len(certificates) == 0 {
- return nil, errors.New("no certificates is found")
- }
-
- return certificates[0], nil
- }
-
- func (c *connectionServer) run() {
- logger := zap.S().Named("tls-connection-server")
-
- ticker := time.NewTicker(connectionServerUpdateEvery)
- defer ticker.Stop()
-
- for {
- select {
- case <-c.ctx.Done():
- return
- case resp := <-c.channelGet:
- resp <- c.nextReadItem.Value.(*x509.Certificate)
- close(resp)
-
- c.nextReadItem = c.nextReadItem.Next()
- case <-ticker.C:
- cert, err := c.fetch()
- switch err {
- case nil:
- c.nextWriteItem.Value = cert
- c.nextWriteItem = c.nextWriteItem.Next()
- default:
- logger.Warnw("cannot fetch certificates", "error", err)
- }
- }
- }
- }
|