mirror of
https://github.com/bdnugget/eggos.git
synced 2026-11-07 04:17:27 +00:00
add socket syscall
This commit is contained in:
1 parent
73bd2662a6
commit
d571314a41
14 files changed
+256
-169
No files matched your search
+9
-1
@@ -25,6 +25,8 @@ type console struct {
|
||||
|
||||
mutex sync.Mutex
|
||||
notify *sync.Cond
|
||||
|
||||
wmutex sync.Mutex
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -135,6 +137,8 @@ func (c *console) Read(p []byte) (int, error) {
|
||||
}
|
||||
|
||||
func (c *console) Write(p []byte) (int, error) {
|
||||
c.wmutex.Lock()
|
||||
defer c.wmutex.Unlock()
|
||||
for _, ch := range p {
|
||||
c.putc(ch)
|
||||
}
|
||||
@@ -167,12 +171,16 @@ type winSize struct {
|
||||
xpixel, ypixel uint16
|
||||
}
|
||||
|
||||
var cononce sync.Once
|
||||
|
||||
func Console() io.ReadWriter {
|
||||
cononce.Do(func() {
|
||||
con = newConsole()
|
||||
})
|
||||
return con
|
||||
}
|
||||
|
||||
func Init() {
|
||||
con = newConsole()
|
||||
uart.OnInput(con.intr)
|
||||
kbd.OnInput(con.intr)
|
||||
}
|
||||
+4
-7
@@ -1,21 +1,18 @@
|
||||
package debug
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/icexin/eggos/console"
|
||||
"github.com/icexin/eggos/drivers/uart"
|
||||
"github.com/icexin/eggos/sys"
|
||||
)
|
||||
|
||||
var (
|
||||
bootTime = time.Now()
|
||||
lastTime = time.Now()
|
||||
)
|
||||
|
||||
func Logf(fmtstr string, args ...interface{}) {
|
||||
fmt.Fprintf(console.Console(), fmtstr+"\n", args...)
|
||||
buf := bytes.Buffer{}
|
||||
fmt.Fprintf(&buf, fmtstr+"\n", args...)
|
||||
buf.WriteTo(console.Console())
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
||||
@@ -31,11 +31,7 @@ func kernelInit() {
|
||||
vbe.Init()
|
||||
fbcga.Init()
|
||||
pci.Init()
|
||||
|
||||
err := inet.Init()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
inet.Init()
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -86,7 +86,7 @@ func fscall(fn int) isyscall.Handler {
|
||||
} else {
|
||||
c.SetRet(uintptr(fd))
|
||||
}
|
||||
c.Done()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ func fscall(fn int) isyscall.Handler {
|
||||
ni, err = GetInode(int(c.Arg(0)))
|
||||
if err != nil {
|
||||
c.SetRet(isyscall.Error(err))
|
||||
c.Done()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ func fscall(fn int) isyscall.Handler {
|
||||
if err != nil {
|
||||
c.SetError(err)
|
||||
}
|
||||
c.Done()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +195,6 @@ func sysIoctl(ni *Inode, op, arg uintptr) error {
|
||||
|
||||
func sysFcntl(call *isyscall.Request) {
|
||||
call.SetRet(0)
|
||||
call.Done()
|
||||
}
|
||||
|
||||
// func Uname(buf *Utsname)
|
||||
@@ -211,7 +210,7 @@ func sysUname(c *isyscall.Request) {
|
||||
copy(unsafebuf(&buf.Sysname), "eggos")
|
||||
copy(unsafebuf(&buf.Version), "0")
|
||||
c.SetRet(0)
|
||||
c.Done()
|
||||
|
||||
}
|
||||
|
||||
// func fstatat(dirfd int, path string, stat *Stat_t, flags int)
|
||||
@@ -225,14 +224,14 @@ func sysFstatat64(c *isyscall.Request) {
|
||||
} else {
|
||||
c.SetRet(isyscall.Error(err))
|
||||
}
|
||||
c.Done()
|
||||
|
||||
return
|
||||
}
|
||||
stat.Mode = uint32(info.Mode())
|
||||
stat.Mtim.Sec = int64(info.ModTime().Unix())
|
||||
stat.Size = info.Size()
|
||||
c.SetRet(0)
|
||||
c.Done()
|
||||
|
||||
}
|
||||
|
||||
func sysRandom(call *isyscall.Request) {
|
||||
@@ -240,7 +239,6 @@ func sysRandom(call *isyscall.Request) {
|
||||
buf := sys.UnsafeBuffer(p, int(n))
|
||||
rand.Read(buf)
|
||||
call.SetRet(n)
|
||||
call.Done()
|
||||
}
|
||||
|
||||
func cstring(ptr uintptr) string {
|
||||
|
||||
+102
-84
@@ -1,11 +1,8 @@
|
||||
package inet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/icexin/eggos/debug"
|
||||
"github.com/icexin/eggos/kernel/isyscall"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
@@ -15,93 +12,16 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/waiter"
|
||||
)
|
||||
|
||||
const (
|
||||
// see linux/net.h
|
||||
_SOCKET = 1
|
||||
_BIND = 2
|
||||
_CONNECT = 3
|
||||
_LISTEN = 4
|
||||
_ACCEPT = 5
|
||||
_GETSOCKNAME = 6
|
||||
_GETPEERNAME = 7
|
||||
_SOCKETPAIR = 8
|
||||
_SEND = 9
|
||||
_RECV = 10
|
||||
_SENDTO = 11
|
||||
_RECVFROM = 12
|
||||
_SHUTDOWN = 13
|
||||
_SETSOCKOPT = 14
|
||||
_GETSOCKOPT = 15
|
||||
_SENDMSG = 16
|
||||
_RECVMSG = 17
|
||||
_ACCEPT4 = 18
|
||||
_RECVMMSG = 19
|
||||
_SENDMMSG = 20
|
||||
)
|
||||
|
||||
func socketcall(c *isyscall.Request) {
|
||||
// Kernel interface gets call sub-number and pointer to a0.
|
||||
// see syscall/asm_linux_386.s rawsocketcall
|
||||
fn := c.Arg(0)
|
||||
args := (*[5]uintptr)(unsafe.Pointer(c.Arg(1)))
|
||||
|
||||
if fn == _SOCKET {
|
||||
// c.SetRet(sysSocket(uintptr(args[0]), uintptr(args[1]), uintptr(args[2])))
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
c.SetRet(0)
|
||||
|
||||
sf, err := findSockFile(args[0])
|
||||
if err != nil {
|
||||
c.SetRet(isyscall.Error(err))
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
switch fn {
|
||||
case _LISTEN:
|
||||
err = sf.Listen(args[1])
|
||||
case _ACCEPT4:
|
||||
var fd int
|
||||
fd, err = sf.Accept4(args[1], args[2], args[3])
|
||||
c.SetRet(uintptr(fd))
|
||||
case _BIND:
|
||||
err = sf.Bind(args[1], args[2])
|
||||
case _CONNECT:
|
||||
err = sf.Connect(args[1], args[2])
|
||||
case _SETSOCKOPT:
|
||||
err = sf.Setsockopt(args[1], args[2], args[3], args[4])
|
||||
case _GETSOCKOPT:
|
||||
err = sf.Getsockopt(args[1], args[2], args[3], args[4])
|
||||
case _GETPEERNAME:
|
||||
err = sf.Getpeername(args[1], args[2])
|
||||
case _GETSOCKNAME:
|
||||
err = sf.Getsockname(args[1], args[2])
|
||||
|
||||
default:
|
||||
debug.Logf("[socket] usupport fn:%d", fn)
|
||||
err = fmt.Errorf("unsupported socket fn:%d", fn)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
c.SetRet(isyscall.Error(err))
|
||||
}
|
||||
c.Done()
|
||||
}
|
||||
|
||||
func sysSocket(c *isyscall.Request) {
|
||||
domain := c.Arg(0)
|
||||
typ := c.Arg(1)
|
||||
// proto := c.Arg(2)
|
||||
if domain != syscall.AF_INET {
|
||||
c.SetErrorNO(syscall.EINVAL)
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
if typ&syscall.SOCK_STREAM == 0 && typ&syscall.SOCK_DGRAM == 0 {
|
||||
c.SetErrorNO(syscall.EINVAL)
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -119,13 +39,12 @@ func sysSocket(c *isyscall.Request) {
|
||||
ep, err := nstack.NewEndpoint(protoNum, ipv4.ProtocolNumber, wq)
|
||||
if err != nil {
|
||||
c.SetError(e(err))
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
sfile := allocSockFile(ep, wq)
|
||||
c.SetRet(uintptr(sfile.fd))
|
||||
c.Done()
|
||||
|
||||
}
|
||||
|
||||
func sysListen(c *isyscall.Request) {
|
||||
@@ -137,11 +56,103 @@ func sysListen(c *isyscall.Request) {
|
||||
err = sf.Listen(c.Arg(1))
|
||||
if err != nil {
|
||||
c.SetError(err)
|
||||
return
|
||||
}
|
||||
c.SetRet(0)
|
||||
}
|
||||
|
||||
func sysAccept(c *isyscall.Request) {
|
||||
func sysBind(c *isyscall.Request) {
|
||||
sf, err := findSockFile(c.Arg(0))
|
||||
if err != nil {
|
||||
c.SetError(err)
|
||||
return
|
||||
}
|
||||
err = sf.Bind(c.Arg(1), c.Arg(2))
|
||||
if err != nil {
|
||||
c.SetError(err)
|
||||
return
|
||||
}
|
||||
c.SetRet(0)
|
||||
|
||||
}
|
||||
|
||||
func sysAccept4(c *isyscall.Request) {
|
||||
sf, err := findSockFile(c.Arg(0))
|
||||
if err != nil {
|
||||
c.SetError(err)
|
||||
return
|
||||
}
|
||||
fd, err := sf.Accept4(c.Arg(1), c.Arg(2), c.Arg(3))
|
||||
if err != nil {
|
||||
c.SetError(err)
|
||||
return
|
||||
}
|
||||
c.SetRet(uintptr(fd))
|
||||
|
||||
}
|
||||
|
||||
func sysConnect(c *isyscall.Request) {
|
||||
sf, err := findSockFile(c.Arg(0))
|
||||
if err != nil {
|
||||
c.SetError(err)
|
||||
return
|
||||
}
|
||||
uaddr := c.Arg(1)
|
||||
uaddrlen := c.Arg(2)
|
||||
err = sf.Connect(uaddr, uaddrlen)
|
||||
c.SetError(err)
|
||||
}
|
||||
|
||||
func sysSetsockopt(c *isyscall.Request) {
|
||||
sf, err := findSockFile(c.Arg(0))
|
||||
if err != nil {
|
||||
c.SetError(err)
|
||||
return
|
||||
}
|
||||
err = sf.Setsockopt(c.Arg(1), c.Arg(2), c.Arg(3), c.Arg(4))
|
||||
// if err != nil {
|
||||
// err = isyscall.EPANIC
|
||||
// }
|
||||
c.SetError(err)
|
||||
}
|
||||
|
||||
func sysGetsockopt(c *isyscall.Request) {
|
||||
sf, err := findSockFile(c.Arg(0))
|
||||
if err != nil {
|
||||
c.SetError(err)
|
||||
return
|
||||
}
|
||||
v, err := sf.Getsockopt(c.Arg(1), c.Arg(2), c.Arg(3), c.Arg(4))
|
||||
if err != nil {
|
||||
c.SetError(err)
|
||||
}
|
||||
c.SetRet(v)
|
||||
}
|
||||
|
||||
func sysGetsockname(c *isyscall.Request) {
|
||||
sf, err := findSockFile(c.Arg(0))
|
||||
if err != nil {
|
||||
c.SetError(err)
|
||||
return
|
||||
}
|
||||
err = sf.Getsockname(c.Arg(1), c.Arg(2))
|
||||
// if err != nil {
|
||||
// err = isyscall.EPANIC
|
||||
// }
|
||||
c.SetError(err)
|
||||
}
|
||||
|
||||
func sysGetpeername(c *isyscall.Request) {
|
||||
sf, err := findSockFile(c.Arg(0))
|
||||
if err != nil {
|
||||
c.SetError(err)
|
||||
return
|
||||
}
|
||||
err = sf.Getpeername(c.Arg(1), c.Arg(2))
|
||||
// if err != nil {
|
||||
// err = isyscall.EPANIC
|
||||
// }
|
||||
c.SetError(err)
|
||||
}
|
||||
|
||||
func ntohs(n uint16) uint16 {
|
||||
@@ -154,5 +165,12 @@ func htons(n uint16) uint16 {
|
||||
|
||||
func init() {
|
||||
isyscall.Register(syscall.SYS_SOCKET, sysSocket)
|
||||
// isyscall.Register(syscall.SYS_SOCKETCALL, socketcall)
|
||||
isyscall.Register(syscall.SYS_BIND, sysBind)
|
||||
isyscall.Register(syscall.SYS_LISTEN, sysListen)
|
||||
isyscall.Register(syscall.SYS_ACCEPT4, sysAccept4)
|
||||
isyscall.Register(syscall.SYS_CONNECT, sysConnect)
|
||||
isyscall.Register(syscall.SYS_SETSOCKOPT, sysSetsockopt)
|
||||
isyscall.Register(syscall.SYS_GETSOCKOPT, sysGetsockopt)
|
||||
isyscall.Register(syscall.SYS_GETSOCKNAME, sysGetsockname)
|
||||
isyscall.Register(syscall.SYS_GETPEERNAME, sysGetpeername)
|
||||
}
|
||||
+41
-37
@@ -3,24 +3,19 @@ package inet
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/icexin/eggos/debug"
|
||||
"github.com/icexin/eggos/fs"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/waiter"
|
||||
)
|
||||
|
||||
type _sockaddr struct {
|
||||
family uint16
|
||||
port uint16
|
||||
ip [4]byte
|
||||
}
|
||||
|
||||
//go:linkname evnotify github.com/icexin/eggos/kernel.epollNotify
|
||||
func evnotify(fd, events uintptr)
|
||||
|
||||
@@ -121,15 +116,16 @@ func (s *sockFile) evcallback(e *waiter.Entry, mask waiter.EventMask) {
|
||||
}
|
||||
|
||||
func (s *sockFile) Bind(uaddr, uaddrlen uintptr) error {
|
||||
if uaddrlen < unsafe.Sizeof(_sockaddr{}) {
|
||||
var saddr *linux.SockAddrInet
|
||||
if uaddrlen < unsafe.Sizeof(*saddr) {
|
||||
return errors.New("bad bind address")
|
||||
}
|
||||
saddr := (*_sockaddr)(unsafe.Pointer(uaddr))
|
||||
ip := net.IPv4(saddr.ip[0], saddr.ip[1], saddr.ip[2], saddr.ip[3])
|
||||
saddr = (*linux.SockAddrInet)(unsafe.Pointer(uaddr))
|
||||
ip := net.IPv4(saddr.Addr[0], saddr.Addr[1], saddr.Addr[2], saddr.Addr[3])
|
||||
addr := tcpip.FullAddress{
|
||||
NIC: defaultNIC,
|
||||
Addr: tcpip.Address(ip),
|
||||
Port: ntohs(saddr.port),
|
||||
Port: ntohs(saddr.Port),
|
||||
}
|
||||
err := s.ep.Bind(addr)
|
||||
if err != nil {
|
||||
@@ -139,13 +135,14 @@ func (s *sockFile) Bind(uaddr, uaddrlen uintptr) error {
|
||||
}
|
||||
|
||||
func (s *sockFile) Connect(uaddr, uaddrlen uintptr) error {
|
||||
if uaddrlen < unsafe.Sizeof(_sockaddr{}) {
|
||||
var saddr *linux.SockAddrInet
|
||||
if uaddrlen < unsafe.Sizeof(*saddr) {
|
||||
return syscall.EINVAL
|
||||
}
|
||||
saddr := (*_sockaddr)(unsafe.Pointer(uaddr))
|
||||
saddr = (*linux.SockAddrInet)(unsafe.Pointer(uaddr))
|
||||
addr := tcpip.FullAddress{
|
||||
Addr: tcpip.Address(saddr.ip[:]),
|
||||
Port: ntohs(saddr.port),
|
||||
Addr: tcpip.Address(saddr.Addr[:]),
|
||||
Port: ntohs(saddr.Port),
|
||||
}
|
||||
err := s.ep.Connect(addr)
|
||||
if _, ok := err.(*tcpip.ErrConnectStarted); ok {
|
||||
@@ -163,10 +160,11 @@ func (s *sockFile) Listen(n uintptr) error {
|
||||
}
|
||||
|
||||
func (s *sockFile) Accept4(uaddr, uaddrlen, flag uintptr) (int, error) {
|
||||
if uaddrlen < unsafe.Sizeof(_sockaddr{}) {
|
||||
var saddr *linux.SockAddrInet
|
||||
if uaddrlen < unsafe.Sizeof(*saddr) {
|
||||
return 0, syscall.EINVAL
|
||||
}
|
||||
saddr := (*_sockaddr)(unsafe.Pointer(uaddr))
|
||||
saddr = (*linux.SockAddrInet)(unsafe.Pointer(uaddr))
|
||||
newep, wq, err := s.ep.Accept(nil)
|
||||
switch err.(type) {
|
||||
case nil:
|
||||
@@ -180,9 +178,9 @@ func (s *sockFile) Accept4(uaddr, uaddrlen, flag uintptr) (int, error) {
|
||||
if err != nil {
|
||||
return 0, e(err)
|
||||
}
|
||||
saddr.family = syscall.AF_INET
|
||||
saddr.port = htons(newaddr.Port)
|
||||
copy(saddr.ip[:], newaddr.Addr)
|
||||
saddr.Family = syscall.AF_INET
|
||||
saddr.Port = htons(newaddr.Port)
|
||||
copy(saddr.Addr[:], newaddr.Addr)
|
||||
sfile := allocSockFile(newep, wq)
|
||||
return sfile.fd, nil
|
||||
}
|
||||
@@ -191,15 +189,17 @@ func (s *sockFile) Setsockopt(level, opt, vptr, vlen uintptr) error {
|
||||
switch level {
|
||||
case syscall.SOL_SOCKET, syscall.IPPROTO_TCP:
|
||||
default:
|
||||
return fmt.Errorf("setsockopt:unsupport socket opt level:%d", level)
|
||||
debug.Logf("[socket] setsockopt:unsupport socket opt level:%d", level)
|
||||
return syscall.EINVAL
|
||||
}
|
||||
|
||||
if vlen != 4 {
|
||||
return errors.New("setsockopt:bad opt value length")
|
||||
debug.Logf("[socket] setsockopt:bad opt value length:%d", vlen)
|
||||
return syscall.EINVAL
|
||||
}
|
||||
|
||||
var terr tcpip.Error
|
||||
value := *(*int32)(unsafe.Pointer(vptr))
|
||||
value := *(*uint32)(unsafe.Pointer(vptr))
|
||||
sockopt := s.ep.SocketOptions()
|
||||
|
||||
switch opt {
|
||||
@@ -218,7 +218,8 @@ func (s *sockFile) Setsockopt(level, opt, vptr, vlen uintptr) error {
|
||||
v := tcpip.KeepaliveIdleOption(time.Duration(value) * time.Second)
|
||||
terr = s.ep.SetSockOpt(&v)
|
||||
default:
|
||||
return fmt.Errorf("setsockopt:unsupport socket opt:%d", level)
|
||||
debug.Logf("[socket] setsockopt:unknow socket option:%d", opt)
|
||||
return syscall.EINVAL
|
||||
}
|
||||
|
||||
if terr != nil {
|
||||
@@ -227,13 +228,15 @@ func (s *sockFile) Setsockopt(level, opt, vptr, vlen uintptr) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *sockFile) Getsockopt(level, opt, vptr, vlenptr uintptr) error {
|
||||
func (s *sockFile) Getsockopt(level, opt, vptr, vlenptr uintptr) (uintptr, error) {
|
||||
if level != syscall.SOL_SOCKET {
|
||||
return fmt.Errorf("unsupport opt level:%d", level)
|
||||
debug.Logf("[socket] getsockopt:unsupport socket opt level:%d", level)
|
||||
return 0, syscall.EINVAL
|
||||
}
|
||||
vlen := (*int)(unsafe.Pointer(vlenptr))
|
||||
if *vlen != 4 {
|
||||
return errors.New("bad opt value length")
|
||||
debug.Logf("[socket] getsockopt:bad opt value length:%d", vlen)
|
||||
return 0, syscall.EINVAL
|
||||
}
|
||||
|
||||
switch opt {
|
||||
@@ -241,34 +244,35 @@ func (s *sockFile) Getsockopt(level, opt, vptr, vlenptr uintptr) error {
|
||||
terr := s.ep.SocketOptions().GetLastError()
|
||||
switch terr.(type) {
|
||||
case *tcpip.ErrConnectionRefused:
|
||||
return syscall.ECONNREFUSED
|
||||
return uintptr(syscall.ECONNREFUSED), nil
|
||||
default:
|
||||
return e(terr)
|
||||
return 0, e(terr)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unknown socket option:%d", opt)
|
||||
debug.Logf("[socket] getsockopt:unknow socket option:%d", opt)
|
||||
return 0, syscall.EINVAL
|
||||
}
|
||||
return nil
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (s *sockFile) Getpeername(uaddr, uaddrlen uintptr) error {
|
||||
saddr := (*_sockaddr)(unsafe.Pointer(uaddr))
|
||||
saddr := (*linux.SockAddrInet)(unsafe.Pointer(uaddr))
|
||||
addr, err := s.ep.GetRemoteAddress()
|
||||
if err != nil {
|
||||
return e(err)
|
||||
}
|
||||
saddr.family = syscall.AF_INET
|
||||
copy(saddr.ip[:], addr.Addr)
|
||||
saddr.Family = syscall.AF_INET
|
||||
copy(saddr.Addr[:], addr.Addr)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *sockFile) Getsockname(uaddr, uaddrlen uintptr) error {
|
||||
saddr := (*_sockaddr)(unsafe.Pointer(uaddr))
|
||||
saddr := (*linux.SockAddrInet)(unsafe.Pointer(uaddr))
|
||||
addr, err := s.ep.GetLocalAddress()
|
||||
if err != nil {
|
||||
return e(err)
|
||||
}
|
||||
saddr.family = syscall.AF_INET
|
||||
copy(saddr.ip[:], addr.Addr)
|
||||
saddr.Family = syscall.AF_INET
|
||||
copy(saddr.Addr[:], addr.Addr)
|
||||
return nil
|
||||
}
|
||||
+20
-11
@@ -3,6 +3,7 @@ package inet
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/icexin/eggos/debug"
|
||||
@@ -10,6 +11,7 @@ import (
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/link/loopback"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/network/arp"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
@@ -18,7 +20,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
defaultNIC = 1
|
||||
defaultNIC = 1
|
||||
loopbackNIC = 2
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -32,7 +35,7 @@ func e(err tcpip.Error) error {
|
||||
return errors.New(err.String())
|
||||
}
|
||||
|
||||
func Init() error {
|
||||
func Init() {
|
||||
nstack = stack.New(stack.Options{
|
||||
NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol},
|
||||
TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol},
|
||||
@@ -40,18 +43,24 @@ func Init() error {
|
||||
endpoint := New(&Options{})
|
||||
err := nstack.CreateNIC(defaultNIC, endpoint)
|
||||
if err != nil {
|
||||
return e(err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = nstack.CreateNIC(loopbackNIC, loopback.New())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = nstack.AddAddress(loopbackNIC, ipv4.ProtocolNumber, tcpip.Address([]byte{127, 0, 0, 1}))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// err = nstack.AddAddress(defaultNIC, arp.ProtocolNumber, arp.ProtocolAddress)
|
||||
// if err != nil {
|
||||
// return e(err)
|
||||
// }
|
||||
|
||||
err1 := dodhcp(endpoint.LinkAddress())
|
||||
if err1 != nil {
|
||||
return err1
|
||||
panic(err)
|
||||
}
|
||||
return nil
|
||||
fmt.Printf("%v\n", nstack.GetRouteTable())
|
||||
return
|
||||
|
||||
nstack.AddAddress(defaultNIC, ipv4.ProtocolNumber, tcpip.Address([]byte{10, 0, 2, 15}))
|
||||
// nstack.AddAddress(defaultNIC, ipv4.ProtocolNumber, tcpip.Address([]byte{10, 0, 0, 7}))
|
||||
@@ -61,7 +70,6 @@ func Init() error {
|
||||
// Gateway: tcpip.Address([]byte{10, 0, 0, 1}),
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dodhcp(linkaddr tcpip.LinkAddress) error {
|
||||
@@ -90,6 +98,7 @@ func setroute(nstack *stack.Stack, cfg dhcp.Config) {
|
||||
Destination: header.IPv4EmptySubnet,
|
||||
Gateway: cfg.Gateway,
|
||||
NIC: defaultNIC,
|
||||
}},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -6,6 +6,10 @@ import (
|
||||
_ "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
EPANIC syscall.Errno = 0xfffff
|
||||
)
|
||||
|
||||
var (
|
||||
handlers [512]Handler
|
||||
)
|
||||
@@ -36,6 +40,11 @@ func (r *Request) SetRet(v uintptr) {
|
||||
r.tf.SetRet(v)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func (r *Request) Ret() uintptr {
|
||||
return r.tf.Ret()
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func (r *Request) SetErrorNO(errno syscall.Errno) {
|
||||
r.SetRet(Errno(errno))
|
||||
@@ -47,8 +56,7 @@ func (r *Request) SetError(err error) {
|
||||
r.SetRet(0)
|
||||
return
|
||||
}
|
||||
fmt.Printf("syscall error: %s\n", err)
|
||||
r.SetErrorNO(syscall.EINVAL)
|
||||
r.SetRet(Error(err))
|
||||
}
|
||||
|
||||
func (r *Request) Done() {
|
||||
@@ -75,5 +83,6 @@ func Error(err error) uintptr {
|
||||
return Errno(code)
|
||||
}
|
||||
fmt.Printf("syscall error: %s\n", err)
|
||||
return ^uintptr(0)
|
||||
ret := uintptr(syscall.EINVAL)
|
||||
return -ret
|
||||
}
|
||||
@@ -50,3 +50,8 @@ func (t *trapFrame) Arg(n int) uintptr {
|
||||
func (t *trapFrame) SetRet(v uintptr) {
|
||||
t.AX = v
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func (t *trapFrame) Ret() uintptr {
|
||||
return t.AX
|
||||
}
|
||||
@@ -35,6 +35,7 @@ func throwtf(tf *trapFrame, msg string) {
|
||||
debug.PrintStr("\n")
|
||||
}
|
||||
|
||||
debug.QemuExit(0xff)
|
||||
for {
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -147,7 +147,9 @@ func canForward(req *isyscall.Request) bool {
|
||||
//go:nosplit
|
||||
func blocksyscall() {
|
||||
tf := *&Mythread().systf
|
||||
ret, _, errno := syscall.Syscall6(tf.AX, tf.BX, tf.CX, tf.DX, tf.SI, tf.DI, tf.BP)
|
||||
c := tf.SyscallRequest()
|
||||
ret, _, errno := syscall.Syscall6(c.NO(), c.Arg(0), c.Arg(1), c.Arg(2),
|
||||
c.Arg(3), c.Arg(4), c.Arg(5))
|
||||
if errno != 0 {
|
||||
sys.SetAX(-uintptr(errno))
|
||||
} else {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/icexin/eggos/debug"
|
||||
"github.com/icexin/eggos/kernel/isyscall"
|
||||
"github.com/icexin/eggos/sys"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -29,6 +30,11 @@ func forwardCall(call *isyscall.Request) {
|
||||
|
||||
// wait on syscall task handle request
|
||||
sleepon(&call.Lock)
|
||||
|
||||
// for debug purpose
|
||||
if -call.Ret() == uintptr(isyscall.EPANIC) {
|
||||
preparePanic(Mythread().tf)
|
||||
}
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
@@ -56,14 +62,34 @@ func runSyscallThread() {
|
||||
throw("bad SYS_WAIT_SYSCALL return")
|
||||
}
|
||||
call := (*isyscall.Request)(unsafe.Pointer(callptr))
|
||||
handler := isyscall.GetHandler(call.NO())
|
||||
|
||||
no := call.NO()
|
||||
handler := isyscall.GetHandler(no)
|
||||
if handler == nil {
|
||||
debug.Logf("[syscall] unhandled syscall %s(%d)", syscallName(int(call.NO())), call.NO())
|
||||
// call.SetRet(isyscall.Errno(syscall.EINVAL))
|
||||
// call.SetRet(isyscall.Errno(syscall.EPERM))
|
||||
debug.Logf("[syscall] unhandled syscall %s(%d)", syscallName(int(no)), no)
|
||||
call.SetErrorNO(syscall.ENOSYS)
|
||||
call.Done()
|
||||
continue
|
||||
}
|
||||
go handler(call)
|
||||
go func() {
|
||||
handler(call)
|
||||
var iret interface{}
|
||||
ret := call.Ret()
|
||||
if hasErrno(ret) {
|
||||
iret = syscall.Errno(-ret)
|
||||
} else {
|
||||
iret = ret
|
||||
}
|
||||
debug.Logf("[syscall] %s(%d)(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) = %v",
|
||||
syscallName(int(no)), no,
|
||||
call.Arg(0), call.Arg(1), call.Arg(2), call.Arg(3),
|
||||
call.Arg(4), call.Arg(5), iret,
|
||||
)
|
||||
call.Done()
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func hasErrno(n uintptr) bool {
|
||||
return 1<<(sys.PtrSize*8-1)&n != 0
|
||||
}
|
||||
+12
-1
@@ -103,6 +103,16 @@ func Test() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestDebug() error {
|
||||
kernelTarget = KernelTest
|
||||
err := QemuDebug()
|
||||
status := mg.ExitStatus(err)
|
||||
if status != 0 && status != 1 {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Qemu run multiboot.elf on qemu.
|
||||
// If env QEMU_ACCEL is set,QEMU acceleration will be enabled.
|
||||
// If env QEMU_GRAPHIC is set QEMU will run in graphic mode.
|
||||
@@ -113,6 +123,7 @@ func Qemu() error {
|
||||
detectQemu()
|
||||
args := append([]string{}, QEMU_OPT...)
|
||||
args = append(args, "-kernel", "multiboot.elf")
|
||||
args = append(args, "-append", os.Getenv("EGGOS_ARGS"))
|
||||
return sh.RunV(QEMU64, args...)
|
||||
}
|
||||
|
||||
@@ -125,6 +136,7 @@ func QemuDebug() error {
|
||||
detectQemu()
|
||||
args := append([]string{}, QEMU_DEBUG_OPT...)
|
||||
args = append(args, "-kernel", "multiboot.elf")
|
||||
args = append(args, "-append", os.Getenv("EGGOS_ARGS"))
|
||||
return sh.RunV(QEMU64, args...)
|
||||
}
|
||||
|
||||
@@ -293,7 +305,6 @@ func initQemuOpt() []string {
|
||||
if os.Getenv("QEMU_GRAPHIC") == "" {
|
||||
out = append(out, "-nographic")
|
||||
}
|
||||
out = append(out, "-append", os.Getenv("EGGOS_ARGS"))
|
||||
return out
|
||||
}
|
||||
|
||||
|
||||
+9
-6
@@ -14,7 +14,7 @@ func TestNetworking(t *testing.T) {
|
||||
wg.Add(1)
|
||||
|
||||
server := http.Server{
|
||||
Addr: ":8000",
|
||||
Addr: ":80",
|
||||
}
|
||||
|
||||
go func() {
|
||||
@@ -22,15 +22,18 @@ func TestNetworking(t *testing.T) {
|
||||
|
||||
err := server.ListenAndServe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
t.Error(err)
|
||||
}
|
||||
}()
|
||||
defer func() {
|
||||
server.Shutdown(context.Background())
|
||||
wg.Wait()
|
||||
}()
|
||||
|
||||
resp, err := http.Get("http://127.0.0.1:8000/")
|
||||
resp, err := http.Get("http://127.0.0.1/")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
resp.Body.Close()
|
||||
server.Shutdown(context.Background())
|
||||
wg.Wait()
|
||||
}
|
||||
Reference in new issue
Block a user