mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-10-08 10:56:13 -08:00
* chore(go): use lowercase module import path * ci: scope checks for Go module changes
80 lines
1.8 KiB
Go
80 lines
1.8 KiB
Go
package reactor
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net"
|
|
|
|
"github.com/easytier/easytier/easytier-go/platform"
|
|
)
|
|
|
|
type environmentOperation struct {
|
|
cancel context.CancelFunc
|
|
done bool
|
|
result net.Addr
|
|
err error
|
|
}
|
|
|
|
func (reactor *Reactor) StartLocalAddrForRemote(
|
|
operation uint64,
|
|
remote *net.UDPAddr,
|
|
socketContext platform.SocketContext,
|
|
) error {
|
|
if reactor.services.Environment == nil {
|
|
return fmt.Errorf("environment operation: no connector environment configured")
|
|
}
|
|
ctx, cancel := context.WithCancel(reactor.ctx)
|
|
result := &environmentOperation{cancel: cancel}
|
|
reactor.mu.Lock()
|
|
if err := reactor.claimOperationLocked(operation, operationEnvironment); err != nil {
|
|
reactor.mu.Unlock()
|
|
cancel()
|
|
return err
|
|
}
|
|
reactor.environments[operation] = result
|
|
reactor.workers.Add(1)
|
|
reactor.mu.Unlock()
|
|
|
|
go func() {
|
|
defer reactor.workers.Done()
|
|
address, resolveErr := reactor.services.Environment.LocalAddrForRemote(
|
|
ctx,
|
|
remote,
|
|
socketContext,
|
|
)
|
|
reactor.mu.Lock()
|
|
if reactor.environments[operation] != result {
|
|
reactor.mu.Unlock()
|
|
return
|
|
}
|
|
result.result = address
|
|
result.err = resolveErr
|
|
result.done = true
|
|
reactor.mu.Unlock()
|
|
reactor.signalCompletion()
|
|
}()
|
|
return nil
|
|
}
|
|
|
|
func (reactor *Reactor) TakeLocalAddrForRemote(operation uint64) (net.Addr, error) {
|
|
reactor.mu.Lock()
|
|
result, exists := reactor.environments[operation]
|
|
if !exists || reactor.operations[operation] != operationEnvironment {
|
|
reactor.mu.Unlock()
|
|
return nil, ErrInvalid
|
|
}
|
|
if !result.done {
|
|
reactor.mu.Unlock()
|
|
return nil, ErrPending
|
|
}
|
|
delete(reactor.environments, operation)
|
|
reactor.releaseOperationLocked(operation, operationEnvironment)
|
|
result.cancel()
|
|
address, err := result.result, result.err
|
|
reactor.mu.Unlock()
|
|
if err == nil && address == nil {
|
|
err = fmt.Errorf("connector environment returned no address")
|
|
}
|
|
return address, err
|
|
}
|