-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
96 lines (75 loc) · 1.83 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package main
import (
"bytes"
"errors"
"flag"
"log"
"net"
"os"
"strings"
"github.com/loopholelabs/userfaultfd-go/pkg/mapper"
"github.com/loopholelabs/userfaultfd-go/pkg/transfer"
)
type abcReader struct{}
func (a abcReader) ReadAt(p []byte, off int64) (n int, err error) {
log.Println("Reading at offset", off)
n = copy(p, bytes.Repeat([]byte{'A' + byte(off%20)}, len(p)))
return n, nil
}
func main() {
socket := flag.String("socket", "userfaultd.sock", "Socket to share the file descriptor over")
server := flag.Bool("server", false, "Whether to serve as the server instead of the client")
length := flag.Int("length", os.Getpagesize()*2, "Amount of bytes to allocate")
flag.Parse()
if strings.TrimSpace(*socket) == "" {
panic(errors.New("could not work with empty socket path"))
}
addr, err := net.ResolveUnixAddr("unix", *socket)
if err != nil {
panic(err)
}
if *server {
lis, err := net.ListenUnix("unix", addr)
if err != nil {
panic(err)
}
log.Println("Listening on", addr.String())
for {
conn, err := lis.AcceptUnix()
if err != nil {
panic(err)
}
go func() {
defer func() {
if err := recover(); err != nil {
log.Println("Could not handle connection, stopping:", err)
}
_ = conn.Close()
}()
uffd, start, err := transfer.ReceiveUFFD(conn)
if err != nil {
panic(err)
}
if err := mapper.Handle(uffd, start, abcReader{}); err != nil {
panic(err)
}
}()
}
} else {
conn, err := net.DialUnix("unix", nil, addr)
if err != nil {
panic(err)
}
log.Println("Connected to", conn.RemoteAddr())
b, uffd, start, err := mapper.Register(*length)
if err != nil {
panic(err)
}
if err := transfer.SendUFFD(conn, uffd, start); err != nil {
panic(err)
}
for i, c := range b {
log.Printf("%v %c", i, rune(c))
}
}
}