mirror of
https://github.com/wyx2685/V2bX.git
synced 2025-01-23 10:28:13 -05:00
d76c6a73eb
add conditional compilation support add multi core support
96 lines
2.0 KiB
Go
96 lines
2.0 KiB
Go
package hy
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"sync"
|
|
|
|
"github.com/fsnotify/fsnotify"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type keypairLoader struct {
|
|
certMu sync.RWMutex
|
|
cert *tls.Certificate
|
|
certPath string
|
|
keyPath string
|
|
}
|
|
|
|
func newKeypairLoader(certPath, keyPath string) (*keypairLoader, error) {
|
|
loader := &keypairLoader{
|
|
certPath: certPath,
|
|
keyPath: keyPath,
|
|
}
|
|
cert, err := tls.LoadX509KeyPair(certPath, keyPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
loader.cert = &cert
|
|
watcher, err := fsnotify.NewWatcher()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
go func() {
|
|
for {
|
|
select {
|
|
case event, ok := <-watcher.Events:
|
|
if !ok {
|
|
return
|
|
}
|
|
switch event.Op {
|
|
case fsnotify.Create, fsnotify.Write, fsnotify.Rename, fsnotify.Chmod:
|
|
logrus.WithFields(logrus.Fields{
|
|
"file": event.Name,
|
|
}).Info("Keypair change detected, reloading...")
|
|
if err := loader.load(); err != nil {
|
|
logrus.WithFields(logrus.Fields{
|
|
"error": err,
|
|
}).Error("Failed to reload keypair")
|
|
} else {
|
|
logrus.Info("Keypair successfully reloaded")
|
|
}
|
|
case fsnotify.Remove:
|
|
_ = watcher.Add(event.Name) // Workaround for vim
|
|
// https://github.com/fsnotify/fsnotify/issues/92
|
|
}
|
|
case err, ok := <-watcher.Errors:
|
|
if !ok {
|
|
return
|
|
}
|
|
logrus.WithFields(logrus.Fields{
|
|
"error": err,
|
|
}).Error("Failed to watch keypair files for changes")
|
|
}
|
|
}
|
|
}()
|
|
err = watcher.Add(certPath)
|
|
if err != nil {
|
|
_ = watcher.Close()
|
|
return nil, err
|
|
}
|
|
err = watcher.Add(keyPath)
|
|
if err != nil {
|
|
_ = watcher.Close()
|
|
return nil, err
|
|
}
|
|
return loader, nil
|
|
}
|
|
|
|
func (kpr *keypairLoader) load() error {
|
|
cert, err := tls.LoadX509KeyPair(kpr.certPath, kpr.keyPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
kpr.certMu.Lock()
|
|
kpr.cert = &cert
|
|
kpr.certMu.Unlock()
|
|
return nil
|
|
}
|
|
|
|
func (kpr *keypairLoader) GetCertificateFunc() func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
|
|
return func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
|
kpr.certMu.RLock()
|
|
defer kpr.certMu.RUnlock()
|
|
return kpr.cert, nil
|
|
}
|
|
}
|