func (ipsec *IPSec) InitSALocal(localPeer, remotePeer mesh.PeerName, connUID uint64, localIP, remoteIP net.IP, udpPort int, sessionKey *[32]byte, initRemote func([]byte) error) error {
	// ID of inbound SPI
	spiID := getSPIId(remotePeer, localPeer, connUID)

	ipsec.Lock()
	defer ipsec.Unlock()

	// Derive SA key
	nonce, err := genNonce()
	if err != nil {
		return errors.Wrap(err, "generate nonce")
	}
	key, err := deriveKey(sessionKey[:], nonce, localPeer)
	if err != nil {
		return errors.Wrap(err, "derive key")
	}

	// Allocate SA
	sa, err := netlink.XfrmStateAllocSpi(xfrmAllocSpiState(remoteIP, localIP))
	if err != nil {
		return errors.Wrap(err, fmt.Sprintf("ip xfrm state allocspi (in, %s, %s)", remoteIP, localIP))
	}

	// Use SPI generated by the kernel. The kernel ensures {dstIP, spi} to
	// be unique.
	spi := SPI(sa.Spi)

	ipsec.log.Infof("ipsec: InitSALocal: %s -> %s :%d 0x%x", remoteIP, localIP, udpPort, spi)

	// Create SA
	if sa, err := xfrmState(remoteIP, localIP, spi, false, key); err == nil {
		if err := netlink.XfrmStateUpdate(sa); err != nil {
			return errors.Wrap(err, fmt.Sprintf("xfrm state update (in, %s, %s, 0x%x)", sa.Src, sa.Dst, sa.Spi))
		}
	} else {
		return errors.Wrap(err, "new xfrm state (in)")
	}

	// Install iptables rules
	if err := ipsec.installDropNonEncrypted(localIP, remoteIP, udpPort, spi); err != nil {
		return errors.Wrap(err, fmt.Sprintf("install protecting rules (%s, %s, %d, 0x%x)", localIP, remoteIP, udpPort, spi))
	}

	si := spiInfo{spi: spi, isDirOut: false}
	ipsec.spiInfo[spiID] = si
	ipsec.spis[spi] = &si

	// Trigger the initialization on the remote peer
	msg := &msgInitSARemote{nonce, spi}
	if err := initRemote(msg.serialize()); err != nil {
		return errors.Wrap(err, "send InitSARemote")
	}

	return nil
}
// InitSALocal initializes inbound ipsec from remotePeer and triggers
// the initialization on remotePeer.
InitSALocal initializes inbound ipsec from remotePeer and triggers
the initialization on remotePeer.
// InitSALocal initializes inbound ipsec from remotePeer and triggers // the initialization on remotePeer .
func (ipsec *IPSec) InitSALocal(localPeer, remotePeer mesh.PeerName, connUID uint64, localIP, remoteIP net.IP, udpPort int, sessionKey *[32]byte, initRemote func([]byte) error) error {
	spiID := getSPIId(remotePeer, localPeer, connUID)
	ipsec.Lock()
	defer ipsec.Unlock()
	nonce, err := genNonce()
	if err != nil {
		return errors.Wrap(err, "generate nonce")
	}
	key, err := deriveKey(sessionKey[:], nonce, localPeer)
	if err != nil {
		return errors.Wrap(err, "derive key")
	}
	sa, err := netlink.XfrmStateAllocSpi(xfrmAllocSpiState(remoteIP, localIP))
	if err != nil {
		return errors.Wrap(err, fmt.Sprintf("ip xfrm state allocspi (in, %s, %s)", remoteIP, localIP))
	}
	spi := SPI(sa.Spi)
	ipsec.log.Infof("ipsec: InitSALocal: %s -> %s :%d 0x%x", remoteIP, localIP, udpPort, spi)
	if sa, err := xfrmState(remoteIP, localIP, spi, false, key); err == nil {
		if err := netlink.XfrmStateUpdate(sa); err != nil {
			return errors.Wrap(err, fmt.Sprintf("xfrm state update (in, %s, %s, 0x%x)", sa.Src, sa.Dst, sa.Spi))
		}
	} else {
		return errors.Wrap(err, "new xfrm state (in)")
	}
	if err := ipsec.installDropNonEncrypted(localIP, remoteIP, udpPort, spi); err != nil {
		return errors.Wrap(err, fmt.Sprintf("install protecting rules (%s, %s, %d, 0x%x)", localIP, remoteIP, udpPort, spi))
	}
	si := spiInfo{spi: spi, isDirOut: false}
	ipsec.spiInfo[spiID] = si
	ipsec.spis[spi] = &si
	msg := &msgInitSARemote{nonce, spi}
	if err := initRemote(msg.serialize()); err != nil {
		return errors.Wrap(err, "send InitSARemote")
	}
	return nil
}
func ( ipsec * IPSec ) InitSALocal ( localPeer , remotePeer mesh . PeerName , connUID uint64 , localIP , remoteIP net . IP , udpPort int , sessionKey * [ 32 ] byte , initRemote func ( [ ] byte ) error ) error { spiID := getSPIId ( remotePeer , localPeer , connUID ) ipsec . Lock ( ) defer ipsec . Unlock ( ) nonce , err := genNonce ( ) if err != nil { return errors . Wrap ( err , " " ) } key , err := deriveKey ( sessionKey [ : ] , nonce , localPeer ) if err != nil { return errors . Wrap ( err , " " ) } sa , err := netlink . XfrmStateAllocSpi ( xfrmAllocSpiState ( remoteIP , localIP ) ) if err != nil { return errors . Wrap ( err , fmt . Sprintf ( " " , remoteIP , localIP ) ) } spi := SPI ( sa . Spi ) ipsec . log . Infof ( " " , remoteIP , localIP , udpPort , spi ) if sa , err := xfrmState ( remoteIP , localIP , spi , false , key ) ; err == nil { if err := netlink . XfrmStateUpdate ( sa ) ; err != nil { return errors . Wrap ( err , fmt . Sprintf ( " " , sa . Src , sa . Dst , sa . Spi ) ) } } else { return errors . Wrap ( err , " " ) } if err := ipsec . installDropNonEncrypted ( localIP , remoteIP , udpPort , spi ) ; err != nil { return errors . Wrap ( err , fmt . Sprintf ( " " , localIP , remoteIP , udpPort , spi ) ) } si := spiInfo { spi : spi , isDirOut : false } ipsec . spiInfo [ spiID ] = si ipsec . spis [ spi ] = & si msg := & msgInitSARemote { nonce , spi } if err := initRemote ( msg . serialize ( ) ) ; err != nil { return errors . Wrap ( err , " " ) } return nil }
InitSALocal initializes inbound ipsec from remotePeer and triggers
the initialization on remotePeer.
InitSALocal initializes inbound ipsec from remotePeer and triggers the initialization on remotePeer .
// ID of inbound SPI // Derive SA key // Allocate SA // Use SPI generated by the kernel. The kernel ensures {dstIP, spi} to // be unique. // Create SA // Install iptables rules // Trigger the initialization on the remote peer