Skip to content

Commit

Permalink
Merge pull request #46 from guillaumerose/forwarderimp
Browse files Browse the repository at this point in the history
Simplify podman machine communication with gvproxy
  • Loading branch information
guillaumerose authored Oct 12, 2021
2 parents fee3bc0 + 384e40b commit 7ce9b6f
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 22 deletions.
57 changes: 36 additions & 21 deletions cmd/gvproxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ var (
exitCode int
)

const gatewayIP = "192.168.127.1"

func main() {
flag.Var(&endpoints, "listen", fmt.Sprintf("URL where the tap send packets (default %s)", transport.DefaultURL))
flag.Var(&endpoints, "listen", "control endpoint")
flag.BoolVar(&debug, "debug", false, "Print debug info")
flag.IntVar(&mtu, "mtu", 1500, "Set the MTU")
flag.IntVar(&sshPort, "ssh-port", 2222, "Port to access the guest virtual machine. Must be between 1024 and 65535")
Expand All @@ -58,9 +60,7 @@ func main() {
if debug {
log.SetLevel(log.DebugLevel)
}
if len(endpoints) == 0 {
endpoints = append(endpoints, transport.DefaultURL)
}

// Make sure the qemu socket provided is valid syntax
if len(qemuSocket) > 0 {
uri, err := url.Parse(qemuSocket)
Expand Down Expand Up @@ -107,7 +107,7 @@ func main() {
CaptureFile: captureFile(),
MTU: mtu,
Subnet: "192.168.127.0/24",
GatewayIP: "192.168.127.1",
GatewayIP: gatewayIP,
GatewayMacAddress: "5a:94:ef:e4:0c:dd",
DHCPStaticLeases: map[string]string{
"192.168.127.2": "5a:94:ef:e4:0c:ee",
Expand All @@ -118,7 +118,7 @@ func main() {
Records: []types.Record{
{
Name: "gateway",
IP: net.ParseIP("192.168.127.1"),
IP: net.ParseIP(gatewayIP),
},
{
Name: "host",
Expand All @@ -131,7 +131,7 @@ func main() {
Records: []types.Record{
{
Name: "gateway",
IP: net.ParseIP("192.168.127.1"),
IP: net.ParseIP(gatewayIP),
},
{
Name: "host",
Expand Down Expand Up @@ -207,21 +207,19 @@ func run(ctx context.Context, g *errgroup.Group, configuration *types.Configurat
if err != nil {
return errors.Wrap(err, "cannot listen")
}
g.Go(func() error {
<-ctx.Done()
return ln.Close()
})
g.Go(func() error {
err := http.Serve(ln, withProfiler(vn))
if err != nil {
if err != http.ErrServerClosed {
return err
}
return err
}
return nil
})
httpServe(ctx, g, ln, withProfiler(vn))
}

ln, err := vn.Listen("tcp", fmt.Sprintf("%s:80", gatewayIP))
if err != nil {
return err
}
mux := http.NewServeMux()
mux.Handle("/services/forwarder/all", vn.Mux())
mux.Handle("/services/forwarder/expose", vn.Mux())
mux.Handle("/services/forwarder/unexpose", vn.Mux())
httpServe(ctx, g, ln, mux)

if debug {
g.Go(func() error {
debugLog:
Expand Down Expand Up @@ -290,6 +288,23 @@ func run(ctx context.Context, g *errgroup.Group, configuration *types.Configurat
return nil
}

func httpServe(ctx context.Context, g *errgroup.Group, ln net.Listener, mux http.Handler) {
g.Go(func() error {
<-ctx.Done()
return ln.Close()
})
g.Go(func() error {
err := http.Serve(ln, mux)
if err != nil {
if err != http.ErrServerClosed {
return err
}
return err
}
return nil
})
}

func withProfiler(vn *virtualnetwork.VirtualNetwork) http.Handler {
mux := vn.Mux()
if debug {
Expand Down
23 changes: 22 additions & 1 deletion pkg/services/forwarder/ports.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,12 @@ func (f *PortsForwarder) Mux() http.Handler {
if req.Protocol == "" {
req.Protocol = types.TCP
}
if err := f.Expose(req.Protocol, req.Local, req.Remote); err != nil {
remote, err := remote(req, r.RemoteAddr)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if err := f.Expose(req.Protocol, req.Local, remote); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
Expand All @@ -187,3 +192,19 @@ func (f *PortsForwarder) Mux() http.Handler {
})
return mux
}

// if the request doesn't have an IP in the remote field, use the IP from the incoming http request.
func remote(req types.ExposeRequest, ip string) (string, error) {
remoteIP, _, err := net.SplitHostPort(req.Remote)
if err != nil {
return "", err
}
if remoteIP == "" {
host, _, err := net.SplitHostPort(ip)
if err != nil {
return "", err
}
return fmt.Sprintf("%s%s", host, req.Remote), nil
}
return req.Remote, nil
}
29 changes: 29 additions & 0 deletions test/port_forwarding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,33 @@ address=/foobar/1.2.3.4
g.Expect(resp.StatusCode).To(Equal(http.StatusOK))
}).Should(Succeed())
})

It("should reach a http server in the VM using dynamic port forwarding configured within the VM", func() {
_, err := sshExec("sudo podman run --rm --name http-test -d -p 8080:80 -t docker.io/library/nginx:alpine")
Expect(err).ShouldNot(HaveOccurred())
defer func() {
_, err := sshExec("sudo podman stop http-test")
Expect(err).ShouldNot(HaveOccurred())
}()

_, err = net.Dial("tcp", "127.0.0.1:9090")
Expect(err.Error()).To(HaveSuffix("connection refused"))

_, err = sshExec(`curl http://gateway.containers.internal/services/forwarder/expose -X POST -d'{"local":":9090", "remote":":8080"}'`)
Expect(err).ShouldNot(HaveOccurred())

Eventually(func(g Gomega) {
resp, err := http.Get("http://127.0.0.1:9090")
g.Expect(err).ShouldNot(HaveOccurred())
g.Expect(resp.StatusCode).To(Equal(http.StatusOK))
}).Should(Succeed())

_, err = sshExec(`curl http://gateway.containers.internal/services/forwarder/unexpose -X POST -d'{"local":":9090"}'`)
Expect(err).ShouldNot(HaveOccurred())

Eventually(func(g Gomega) {
_, err = net.Dial("tcp", "127.0.0.1:9090")
g.Expect(err.Error()).To(HaveSuffix("connection refused"))
}).Should(Succeed())
})
})

0 comments on commit 7ce9b6f

Please sign in to comment.