Skip to content

Commit

Permalink
Merge pull request #429 from lstocchi/i425
Browse files Browse the repository at this point in the history
Add --services flag to start API without using --listen flag
  • Loading branch information
openshift-merge-bot[bot] authored Jan 30, 2025
2 parents c30fc5c + ab9bbf4 commit 45ea6bb
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 41 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ With the executable:

### API

When `gvproxy` is started with the `--listen` option, it exposes a HTTP API on the host.
When `gvproxy` is started with the `--listen` or `--services` option, it exposes a HTTP API on the host.
This API can be used with curl.

```
Expand All @@ -127,6 +127,8 @@ $ curl --unix-socket /tmp/network.sock http:/unix/stats
...
```

N.B: The `--services` option exposes the same HTTP API as the `--listen` option, but without the `/connect` endpoint. This is useful for scenarios where the `gvforwarder`/`vm` tool is not run on the guest but you still want to expose services and stats endpoints.

### Gateway

The executable running on the host runs a virtual gateway that can be used by the VM.
Expand All @@ -144,7 +146,7 @@ nameserver 192.168.127.1
### Port forwarding

Dynamic port forwarding is supported over the host HTTP API when `gvproxy` was
started with `--listen`, but also in the VM over http://192.168.127.1:80.
started with `--listen` or `--services`, but also in the VM over http://192.168.127.1:80.

Expose a port:
```
Expand Down
47 changes: 29 additions & 18 deletions cmd/gvproxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,23 @@ import (
)

var (
debug bool
mtu int
endpoints arrayFlags
vpnkitSocket string
qemuSocket string
bessSocket string
stdioSocket string
vfkitSocket string
forwardSocket arrayFlags
forwardDest arrayFlags
forwardUser arrayFlags
forwardIdentify arrayFlags
sshPort int
pidFile string
exitCode int
logFile string
debug bool
mtu int
endpoints arrayFlags
vpnkitSocket string
qemuSocket string
bessSocket string
stdioSocket string
vfkitSocket string
forwardSocket arrayFlags
forwardDest arrayFlags
forwardUser arrayFlags
forwardIdentify arrayFlags
sshPort int
pidFile string
exitCode int
logFile string
servicesEndpoint string
)

const (
Expand Down Expand Up @@ -74,6 +75,7 @@ func main() {
flag.Var(&forwardIdentify, "forward-identity", "Path to SSH identity key for forwarding")
flag.StringVar(&pidFile, "pid-file", "", "Generate a file with the PID in it")
flag.StringVar(&logFile, "log-file", "", "Output log messages (logrus) to a given file path")
flag.StringVar(&servicesEndpoint, "services", "", "Exposes the same HTTP API as the --listen flag, without the /connect endpoint")
flag.Parse()

if version.ShowVersion() {
Expand Down Expand Up @@ -262,7 +264,7 @@ func main() {
}

groupErrs.Go(func() error {
return run(ctx, groupErrs, &config, endpoints)
return run(ctx, groupErrs, &config, endpoints, servicesEndpoint)
})

// Wait for something to happen
Expand Down Expand Up @@ -310,7 +312,7 @@ func captureFile() string {
return "capture.pcap"
}

func run(ctx context.Context, g *errgroup.Group, configuration *types.Configuration, endpoints []string) error {
func run(ctx context.Context, g *errgroup.Group, configuration *types.Configuration, endpoints []string, servicesEndpoint string) error {
vn, err := virtualnetwork.New(configuration)
if err != nil {
return err
Expand All @@ -326,6 +328,15 @@ func run(ctx context.Context, g *errgroup.Group, configuration *types.Configurat
httpServe(ctx, g, ln, withProfiler(vn))
}

if servicesEndpoint != "" {
log.Infof("enabling services API. Listening %s", servicesEndpoint)
ln, err := transport.Listen(servicesEndpoint)
if err != nil {
return errors.Wrap(err, "cannot listen")
}
httpServe(ctx, g, ln, vn.ServicesMux())
}

ln, err := vn.Listen("tcp", fmt.Sprintf("%s:80", gatewayIP))
if err != nil {
return err
Expand Down
47 changes: 26 additions & 21 deletions pkg/virtualnetwork/mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
)

func (n *VirtualNetwork) Mux() *http.ServeMux {
func (n *VirtualNetwork) ServicesMux() *http.ServeMux {
mux := http.NewServeMux()
mux.Handle("/services/", http.StripPrefix("/services", n.servicesMux))
mux.HandleFunc("/stats", func(w http.ResponseWriter, _ *http.Request) {
Expand All @@ -27,26 +27,6 @@ func (n *VirtualNetwork) Mux() *http.ServeMux {
mux.HandleFunc("/leases", func(w http.ResponseWriter, _ *http.Request) {
_ = json.NewEncoder(w).Encode(n.ipPool.Leases())
})
mux.HandleFunc(types.ConnectPath, func(w http.ResponseWriter, _ *http.Request) {
hj, ok := w.(http.Hijacker)
if !ok {
http.Error(w, "webserver doesn't support hijacking", http.StatusInternalServerError)
return
}
conn, bufrw, err := hj.Hijack()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer conn.Close()

if err := bufrw.Flush(); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

_ = n.networkSwitch.Accept(context.Background(), conn, n.configuration.Protocol)
})
mux.HandleFunc("/tunnel", func(w http.ResponseWriter, r *http.Request) {
ip := r.URL.Query().Get("ip")
if ip == "" {
Expand Down Expand Up @@ -98,3 +78,28 @@ func (n *VirtualNetwork) Mux() *http.ServeMux {
})
return mux
}

func (n *VirtualNetwork) Mux() *http.ServeMux {
mux := n.ServicesMux()
mux.HandleFunc(types.ConnectPath, func(w http.ResponseWriter, _ *http.Request) {
hj, ok := w.(http.Hijacker)
if !ok {
http.Error(w, "webserver doesn't support hijacking", http.StatusInternalServerError)
return
}
conn, bufrw, err := hj.Hijack()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer conn.Close()

if err := bufrw.Flush(); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

_ = n.networkSwitch.Accept(context.Background(), conn, n.configuration.Protocol)
})
return mux
}

0 comments on commit 45ea6bb

Please sign in to comment.