Skip to content

Commit

Permalink
Merge pull request #137 from openziti/issue-135-add-ip-intercept
Browse files Browse the repository at this point in the history
Issue 135 add ip intercept
  • Loading branch information
dovholuknf authored Oct 16, 2020
2 parents 08c6ea5 + b56b04a commit 7e0e9e3
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 187 deletions.
126 changes: 0 additions & 126 deletions service/cziti/cziti-cli/main.go

This file was deleted.

1 change: 0 additions & 1 deletion service/cziti/dns-proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ func runDNSproxy(dnsServers []string) {
b, _ := pr.req.Pack()
for _, proxy := range dnsUpstreams {
if _, err := proxy.Write(b); err != nil {
//TODO: if this happens -does this mean the next dns server is not available?

_ = proxy.Close() //first thing - close the proxy connection

Expand Down
88 changes: 61 additions & 27 deletions service/cziti/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ import "C"
import (
"encoding/binary"
"fmt"
"github.com/openziti/desktop-edge-win/service/ziti-tunnel/constants"

"github.com/openziti/desktop-edge-win/service/ziti-tunnel/api"
"net"
"strings"
"sync"
Expand All @@ -44,12 +43,19 @@ type dnsImpl struct {
cidr uint32
ipCount uint32

serviceMap map[string]ctxService
serviceMap map[intercept]ctxService

// dnsName -> ip address
hostnameMap map[string]ctxIp
// ipv4 -> dnsName
//ipMap map[uint32]string
tun api.DesktopEdgeIface
}

type intercept struct {
host string
port uint16
isIp bool
}

type ctxIp struct {
Expand Down Expand Up @@ -78,20 +84,28 @@ func normalizeDnsName(dnsName string) string {
// RegisterService will return the next ip address in the configured range. If the ip address is not
// assigned to a hostname an error will also be returned indicating why.
func (dns *dnsImpl) RegisterService(svcId string, dnsNameToReg string, port uint16, ctx *CZitiCtx, svcName string) (net.IP, error) {
log.Infof("adding DNS entry for service name %s@%s:%d", svcName, dnsNameToReg, port)
DnsInit(constants.Ipv4ip, constants.Ipv4DefaultMask)
dnsName := normalizeDnsName(dnsNameToReg)
key := fmt.Sprint(dnsName, ':', port)
var ipOrDnsName string

//check to see if host is an ip address - if so we want to intercept the ip. otherwise treat host as a host
//name and register it in dns, obtain an ip and all that...
ip := net.ParseIP(dnsNameToReg)

int := intercept{isIp: false}
if ip == nil {
int.host = normalizeDnsName(dnsNameToReg)
} else {
int.host = ip.String()
}

var ip net.IP
log.Infof("adding DNS for %s. service name %s@%s.", dnsNameToReg, svcName, int)

currentNetwork := C.GoString(ctx.Options.controller)

// check to see if the hostname is mapped...
if foundIp, found := dns.hostnameMap[dnsName]; found {
if foundIp, found := dns.hostnameMap[ipOrDnsName]; found {
ip = foundIp.ip
// now check to see if the host *and* port are mapped...
if foundContext, found := dns.serviceMap[key]; found {
if foundContext, found := dns.serviceMap[int]; found {
if foundIp.network != currentNetwork {
// means the host:port are mapped to some other *identity* already. that's an invalid state
return ip, fmt.Errorf("service mapping conflict for service name %s. %s:%d in %s is already mapped by another identity in %s", svcName, dnsNameToReg, port, currentNetwork, foundIp.network)
Expand All @@ -103,10 +117,10 @@ func (dns *dnsImpl) RegisterService(svcId string, dnsNameToReg string, port uint
// while the host *AND* port are not used - the hostname is.
// need to increment the refcounter of how many service use this hostname
foundContext.count ++
log.Debugf("DNS mapping for %s used by another service. total services using %s = %d", dnsNameToReg, dnsNameToReg, foundContext.count)
log.Debugf("DNS mapping used by another service. total services using %s = %d", dnsNameToReg, foundContext.count)
} else {
// good - means the service can be mapped
dns.serviceMap[key] = ctxService{
dns.serviceMap[int] = ctxService{
ctx: ctx,
name: svcName,
serviceId: svcId,
Expand All @@ -115,17 +129,30 @@ func (dns *dnsImpl) RegisterService(svcId string, dnsNameToReg string, port uint
}
} else {
// if not used at all - map it
nextAddr := dns.cidr | atomic.AddUint32(&dns.ipCount, 1)
ip = make(net.IP, 4)
binary.BigEndian.PutUint32(ip, nextAddr)

log.Infof("mapping hostname %s to ip %s", dnsNameToReg, ip.String())
dns.hostnameMap[dnsName] = ctxIp {
ip: ip,
ctx: ctx,
network: currentNetwork,
if int.isIp {
err := dns.tun.AddRoute(
net.IPNet{IP: ip, Mask: net.IPMask{255, 255, 255, 255}},
net.IP{0,0,0,0},
1)
if err != nil {
log.Errorf("Unexpected error adding a route to %s: %v", ipOrDnsName, err)
} else {
log.Infof("adding route for ip:%s", ipOrDnsName)
}
} else {
nextAddr := dns.cidr | atomic.AddUint32(&dns.ipCount, 1)
ip = make(net.IP, 4)
binary.BigEndian.PutUint32(ip, nextAddr)

log.Infof("mapping hostname %s to ip %s", dnsNameToReg, ip.String())
dns.hostnameMap[ipOrDnsName] = ctxIp {
ip: ip,
ctx: ctx,
network: currentNetwork,
}
}
dns.serviceMap[key] = ctxService{

dns.serviceMap[int] = ctxService{
ctx: ctx,
name: svcName,
serviceId: svcId,
Expand All @@ -143,13 +170,19 @@ func (dns *dnsImpl) Resolve(toResolve string) net.IP {

func (dns *dnsImpl) DeregisterService(ctx *CZitiCtx, name string) {
log.Debugf("DEREG SERVICE: before for loop")
for k, sc := range dns.serviceMap {
for int, sc := range dns.serviceMap {
log.Debugf("DEREG SERVICE: iterating sc.ctx=ctx %p=%p, sc.name=name %s=%s", sc.ctx, ctx, sc.name, name)
if sc.ctx == ctx && sc.name == name {
sc.count --
if sc.count < 1 {
log.Infof("removing service named %s from DNS mapping known as %s", name, k)
delete(dns.serviceMap, k)
log.Infof("removing service named %s from DNS mapping known as %s", name, int)
if int.isIp {
err := dns.tun.RemoveRoute(net.IPNet{IP: net.ParseIP(int.host)}, net.IP{0, 0, 0, 0})
if err != nil {
log.Warnf("Unexpected error removing route for %s", int.host)
}
}
delete(dns.serviceMap, int)
} else {
// another service is using the mapping - can't remove it yet so decrement
log.Debugf("cannot remove dns mapping for %s yet - %d other services still use this hostname", name, sc.count)
Expand Down Expand Up @@ -179,14 +212,15 @@ func (this *dnsImpl) GetService(ip net.IP, port uint16) (*CZitiCtx, string, erro
*/
}

func DnsInit(ip string, maskBits int) {
func DnsInit(tun api.DesktopEdgeIface, ip string, maskBits int) {
initOnce.Do(func() {
DNS.serviceMap = make(map[string]ctxService)
DNS.serviceMap = make(map[intercept]ctxService)
//DNS.ipMap = make(map[uint32]string)
DNS.hostnameMap = make(map[string]ctxIp)
i := net.ParseIP(ip).To4()
mask := net.CIDRMask(maskBits, 32)
DNS.cidr = binary.BigEndian.Uint32(i) & binary.BigEndian.Uint32(mask)
DNS.ipCount = 2
DNS.tun = tun
})
}
2 changes: 1 addition & 1 deletion service/cziti/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func serviceCB(ziti_ctx C.ziti_context, service *C.ziti_service, status C.int, t
ZitiContext: ctx,
}
} else {
log.Warnf("could not remove service? service not found with id: %s, name: %s in context %d", service.id, service.name, &ctx)
log.Warnf("could not remove service? service not found with id: %s, name: %s in context %d", svcId, name, &ctx)
}
} else if status == C.ZITI_OK {
//first thing's first - determine if the service is already in this runtime
Expand Down
4 changes: 4 additions & 0 deletions service/set-env.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
set SVC_ROOT_DIR=%~dp0
SET TUNNELER_SDK_DIR=%SVC_ROOT_DIR%deps\ziti-tunneler-sdk-c\
SET CGO_CFLAGS=-DNOGDI -I %TUNNELER_SDK_DIR%install\include
SET CGO_LDFLAGS=-L %TUNNELER_SDK_DIR%install\lib
29 changes: 29 additions & 0 deletions service/ziti-tunnel/api/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package api

import "net"

type DesktopEdgeIface interface {
AddRoute(destination net.IPNet, nextHop net.IP, metric uint32) error
RemoveRoute(destination net.IPNet, nextHop net.IP) error

InterceptDNS()
ReleaseDNS()

InterceptIP()
ReleaseIP()

Close()
}

type DesktopEdgeManager interface {
AddIdentity()
RemoveIdentity()
Status()
TunnelState()
IdentityToggle()
SetLogLevel()
Debug()
SaveState()
CreateTun()
FindIdentity()
}
4 changes: 2 additions & 2 deletions service/ziti-tunnel/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// +build windows

/*
* Copyright NetFoundry, Inc.
*
Expand All @@ -14,8 +16,6 @@
* limitations under the License.
*
*/

// +build windows
package main

import (
Expand Down
8 changes: 4 additions & 4 deletions service/ziti-tunnel/service/ipc.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ func (p *Pipes) shutdownConnections() {
}

func initialize(ipv4 string, ipv4mask int) error {
err := rts.CreateTun(ipv4, ipv4mask)
err := rts.CreateTun(ipv4, 32)
if err != nil {
return err
}
Expand Down Expand Up @@ -314,7 +314,7 @@ func serveIpc(conn net.Conn) {
events.broadcast <- dto.TunnelStatusEvent{
StatusEvent: dto.StatusEvent{Op: "status"},
Status: rts.ToStatus(),
ApiVersion: API_VERSION,
ApiVersion: API_VERSION,
}

done := make(chan struct{}, 8)
Expand Down Expand Up @@ -523,7 +523,7 @@ func serveEvents(conn net.Conn) {
err := o.Encode( dto.TunnelStatusEvent{
StatusEvent: dto.StatusEvent{Op: "status"},
Status: rts.ToStatus(),
ApiVersion: API_VERSION,
ApiVersion: API_VERSION,
})

if err != nil {
Expand Down Expand Up @@ -795,7 +795,7 @@ func removeIdentity(out *json.Encoder, fingerprint string) {
return
}

rts.RemoveByIdentity(*id)
rts.RemoveByFingerprint(fingerprint)

//remove the file from the filesystem - first verify it's the proper file
log.Debug("removing identity file for fingerprint %s at %s", id.FingerPrint, id.Path())
Expand Down
Loading

0 comments on commit 7e0e9e3

Please sign in to comment.