feature/conn25: call AuthReconfigAsync after address assignment
When the client of a connector assigns transit IP addresses for a connector we need to let wireguard know that packets for the transit IPs should be sent to the connector node. We do this by: * keeping a map of node -> transit IPs we've assigned for it * setting a callback hook within wireguard reconfig to ask us for these extra allowed IPs. * forcing wireguard to do a reconfig after we have assigned new transit IPs. And this commit is the last part: forcing the wireguard reconfig after a new address assignment. Fixes tailscale/corp#38124 Signed-off-by: Fran Bull <fran@tailscale.com>
This commit is contained in:
@@ -603,13 +603,22 @@ func (e *extension) sendLoop(ctx context.Context) {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case as := <-e.conn25.client.addrsCh:
|
||||
if err := e.sendAddressAssignment(ctx, as); err != nil {
|
||||
e.conn25.client.logf("error sending transit IP assignment (app: %s, mip: %v, src: %v): %v", as.app, as.magic, as.dst, err)
|
||||
if err := e.handleAddressAssignment(ctx, as); err != nil {
|
||||
e.conn25.client.logf("error handling transit IP assignment (app: %s, mip: %v, src: %v): %v", as.app, as.magic, as.dst, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (e *extension) handleAddressAssignment(ctx context.Context, as addrs) error {
|
||||
if err := e.sendAddressAssignment(ctx, as); err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO(fran) assign the connector publickey -> transit ip addresses
|
||||
e.host.AuthReconfigAsync()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *client) enqueueAddressAssignment(addrs addrs) error {
|
||||
select {
|
||||
// TODO(fran) investigate the value of waiting for multiple addresses and sending them
|
||||
|
||||
@@ -798,12 +798,14 @@ func (nb *testNodeBackend) PeerAPIBase(p tailcfg.NodeView) string {
|
||||
|
||||
type testHost struct {
|
||||
ipnext.Host
|
||||
nb ipnext.NodeBackend
|
||||
hooks ipnext.Hooks
|
||||
nb ipnext.NodeBackend
|
||||
hooks ipnext.Hooks
|
||||
authReconfigAsync func()
|
||||
}
|
||||
|
||||
func (h *testHost) NodeBackend() ipnext.NodeBackend { return h.nb }
|
||||
func (h *testHost) Hooks() *ipnext.Hooks { return &h.hooks }
|
||||
func (h *testHost) AuthReconfigAsync() { h.authReconfigAsync() }
|
||||
|
||||
type testSafeBackend struct {
|
||||
ipnext.SafeBackend
|
||||
@@ -812,9 +814,11 @@ type testSafeBackend struct {
|
||||
|
||||
func (b *testSafeBackend) Sys() *tsd.System { return b.sys }
|
||||
|
||||
// TestEnqueueAddress tests that after enqueueAddress has been called a
|
||||
// peerapi request is made to a peer.
|
||||
func TestEnqueueAddress(t *testing.T) {
|
||||
// TestAddressAssignmentIsHandled tests that after enqueueAddress has been called
|
||||
// we handle the assignment asynchronously by:
|
||||
// - making a peerapi request to a peer.
|
||||
// - calling AuthReconfigAsync on the host.
|
||||
func TestAddressAssignmentIsHandled(t *testing.T) {
|
||||
// make a fake peer to test against
|
||||
received := make(chan ConnectorTransitIPRequest, 1)
|
||||
peersAPI := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -849,11 +853,15 @@ func TestEnqueueAddress(t *testing.T) {
|
||||
conn25: newConn25(logger.Discard),
|
||||
backend: &testSafeBackend{sys: sys},
|
||||
}
|
||||
authReconfigAsyncCalled := make(chan struct{}, 1)
|
||||
if err := ext.Init(&testHost{
|
||||
nb: &testNodeBackend{
|
||||
peers: []tailcfg.NodeView{connectorPeer},
|
||||
peerAPIURL: peersAPI.URL,
|
||||
},
|
||||
authReconfigAsync: func() {
|
||||
authReconfigAsyncCalled <- struct{}{}
|
||||
},
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -896,6 +904,11 @@ func TestEnqueueAddress(t *testing.T) {
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("timed out waiting for connector to receive request")
|
||||
}
|
||||
select {
|
||||
case <-authReconfigAsyncCalled:
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("timed out waiting for AuthReconfigAsync to be called")
|
||||
}
|
||||
}
|
||||
|
||||
func parseResponse(t *testing.T, buf []byte) ([]dnsmessage.Resource, []dnsmessage.Resource) {
|
||||
|
||||
Reference in New Issue
Block a user