aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2016-11-16 17:03:13 +0100
committerDmitry Vyukov <dvyukov@google.com>2016-11-16 17:03:13 +0100
commitaa9fbfb94b8efc6f3fdc236545a5f34e8f2e3540 (patch)
tree84a00f0dd3a1ac629e1105a70877fe3a71817799
parent1d5ba315b46a39cdc053ad178a33e57542fa4f6e (diff)
syz-gce: proxy manager http requests
Firewall may restrict access to manager, proxy traffic manager requests. Also choose manager port automatically.
-rw-r--r--syz-gce/http.go40
-rw-r--r--syz-gce/syz-gce.go53
2 files changed, 69 insertions, 24 deletions
diff --git a/syz-gce/http.go b/syz-gce/http.go
index b6e86b381..9ce0a4990 100644
--- a/syz-gce/http.go
+++ b/syz-gce/http.go
@@ -6,15 +6,19 @@ package main
import (
"fmt"
"html/template"
+ "io"
"net"
"net/http"
"strings"
+ "sync/atomic"
. "github.com/google/syzkaller/log"
)
func initHttp(addr string) {
- http.HandleFunc("/", httpSummary)
+ http.HandleFunc("/", httpManager)
+ http.HandleFunc("/syz-gce", httpSummary)
+
ln, err := net.Listen("tcp4", addr)
if err != nil {
Fatalf("failed to listen on %v: %v", addr, err)
@@ -28,8 +32,9 @@ func initHttp(addr string) {
func httpSummary(w http.ResponseWriter, r *http.Request) {
data := &UISummaryData{
- Name: cfg.Name,
- Log: CachedLogOutput(),
+ Name: cfg.Name,
+ Manager: atomic.LoadUint32(&managerHttpPort) != 0,
+ Log: CachedLogOutput(),
}
if err := summaryTemplate.Execute(w, data); err != nil {
http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError)
@@ -37,13 +42,28 @@ func httpSummary(w http.ResponseWriter, r *http.Request) {
}
}
+func httpManager(w http.ResponseWriter, r *http.Request) {
+ port := atomic.LoadUint32(&managerHttpPort)
+ if port == 0 {
+ http.Error(w, "manager is not running", http.StatusInternalServerError)
+ return
+ }
+ resp, err := http.Get(fmt.Sprintf("http://localhost:%v/%v", port, r.RequestURI))
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ io.Copy(w, resp.Body)
+}
+
func compileTemplate(html string) *template.Template {
return template.Must(template.New("").Parse(strings.Replace(html, "{{STYLE}}", htmlStyle, -1)))
}
type UISummaryData struct {
- Name string
- Log string
+ Name string
+ Manager bool
+ Log string
}
var summaryTemplate = compileTemplate(`
@@ -55,8 +75,14 @@ var summaryTemplate = compileTemplate(`
</head>
<body>
<b>{{.Name}} syz-gce</b>
-<br>
-<br>
+<br><br>
+
+{{if .Manager}}
+<a href="/">manager</a>
+{{else}}
+manager is not running
+{{end}}
+<br><br>
Log:
<br>
diff --git a/syz-gce/syz-gce.go b/syz-gce/syz-gce.go
index 77b2723ea..8b6da1f42 100644
--- a/syz-gce/syz-gce.go
+++ b/syz-gce/syz-gce.go
@@ -15,11 +15,13 @@ import (
"fmt"
"io"
"io/ioutil"
+ "net"
"os"
"os/exec"
"os/signal"
"path/filepath"
"strings"
+ "sync/atomic"
"syscall"
"time"
@@ -35,23 +37,23 @@ var (
flagNoImageCreate = flag.Bool("noimagecreate", false, "don't download/create image (for testing)")
flagNoRebuild = flag.Bool("norebuild", false, "don't update/rebuild syzkaller (for testing)")
- cfg *Config
- ctx context.Context
- storageClient *storage.Client
- GCE *gce.Context
+ cfg *Config
+ ctx context.Context
+ storageClient *storage.Client
+ GCE *gce.Context
+ managerHttpPort uint32
)
type Config struct {
- Name string
- Image_Archive string
- Image_Path string
- Image_Name string
- Http_Port int
- Manager_Http_Port int
- Machine_Type string
- Machine_Count int
- Sandbox string
- Procs int
+ Name string
+ Image_Archive string
+ Image_Path string
+ Image_Name string
+ Http_Port int
+ Machine_Type string
+ Machine_Count int
+ Sandbox string
+ Procs int
}
func main() {
@@ -98,6 +100,7 @@ func main() {
}
Logf(0, "syz-manager exited with %v", err)
managerCmd = nil
+ atomic.StoreUint32(&managerHttpPort, 0)
case s := <-sigC:
switch s {
case syscall.SIGUSR1:
@@ -194,7 +197,12 @@ func main() {
*flagNoRebuild = false
lastSyzkallerHash = syzkallerHash
- if err := writeManagerConfig("manager.cfg"); err != nil {
+ port, err := chooseUnusedPort()
+ if err != nil {
+ Logf(0, "failed to choose an unused port: %v", err)
+ continue
+ }
+ if err := writeManagerConfig(port, "manager.cfg"); err != nil {
Logf(0, "failed to write manager config: %v", err)
continue
}
@@ -207,6 +215,7 @@ func main() {
continue
}
stoppingManager = false
+ atomic.StoreUint32(&managerHttpPort, uint32(port))
go func() {
managerStopped <- managerCmd.Wait()
}()
@@ -229,7 +238,7 @@ func readConfig(filename string) *Config {
return cfg
}
-func writeManagerConfig(file string) error {
+func writeManagerConfig(httpPort int, file string) error {
tag, err := ioutil.ReadFile("image/tag")
if err != nil {
return fmt.Errorf("failed to read tag file: %v", err)
@@ -239,7 +248,7 @@ func writeManagerConfig(file string) error {
}
managerCfg := &config.Config{
Name: cfg.Name,
- Http: fmt.Sprintf(":%v", cfg.Manager_Http_Port),
+ Http: fmt.Sprintf(":%v", httpPort),
Rpc: ":0",
Workdir: "workdir",
Vmlinux: "image/obj/vmlinux",
@@ -264,6 +273,16 @@ func writeManagerConfig(file string) error {
return nil
}
+func chooseUnusedPort() (int, error) {
+ ln, err := net.Listen("tcp4", ":")
+ if err != nil {
+ return 0, err
+ }
+ port := ln.Addr().(*net.TCPAddr).Port
+ ln.Close()
+ return port, nil
+}
+
func openFile(file string) (*storage.ObjectHandle, time.Time, error) {
pos := strings.IndexByte(file, '/')
if pos == -1 {