github.com/jspc/eggos@v0.5.1-0.20221028160421-556c75c878a5/inet/socket.go (about)

     1  package inet
     2  
     3  import (
     4  	"syscall"
     5  
     6  	"github.com/jspc/eggos/kernel/isyscall"
     7  
     8  	"gvisor.dev/gvisor/pkg/tcpip"
     9  	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
    10  	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
    11  	"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
    12  	"gvisor.dev/gvisor/pkg/waiter"
    13  )
    14  
    15  func sysSocket(c *isyscall.Request) {
    16  	domain := c.Arg(0)
    17  	typ := c.Arg(1)
    18  	// proto := c.Arg(2)
    19  	if domain != syscall.AF_INET {
    20  		c.SetErrorNO(syscall.EINVAL)
    21  		return
    22  	}
    23  	if typ&syscall.SOCK_STREAM == 0 && typ&syscall.SOCK_DGRAM == 0 {
    24  		c.SetErrorNO(syscall.EINVAL)
    25  		return
    26  	}
    27  
    28  	var protoNum tcpip.TransportProtocolNumber
    29  	switch {
    30  	case typ&syscall.SOCK_STREAM != 0:
    31  		protoNum = tcp.ProtocolNumber
    32  	case typ&syscall.SOCK_DGRAM != 0:
    33  		protoNum = udp.ProtocolNumber
    34  	default:
    35  		panic(typ)
    36  	}
    37  
    38  	wq := new(waiter.Queue)
    39  	ep, err := nstack.NewEndpoint(protoNum, ipv4.ProtocolNumber, wq)
    40  	if err != nil {
    41  		c.SetError(e(err))
    42  		return
    43  	}
    44  
    45  	sfile := allocSockFile(ep, wq)
    46  	c.SetRet(uintptr(sfile.fd))
    47  
    48  }
    49  
    50  func sysListen(c *isyscall.Request) {
    51  	sf, err := findSockFile(c.Arg(0))
    52  	if err != nil {
    53  		c.SetError(err)
    54  		return
    55  	}
    56  	err = sf.Listen(c.Arg(1))
    57  	if err != nil {
    58  		c.SetError(err)
    59  		return
    60  	}
    61  	c.SetRet(0)
    62  }
    63  
    64  func sysBind(c *isyscall.Request) {
    65  	sf, err := findSockFile(c.Arg(0))
    66  	if err != nil {
    67  		c.SetError(err)
    68  		return
    69  	}
    70  	err = sf.Bind(c.Arg(1), c.Arg(2))
    71  	if err != nil {
    72  		c.SetError(err)
    73  		return
    74  	}
    75  	c.SetRet(0)
    76  
    77  }
    78  
    79  func sysAccept4(c *isyscall.Request) {
    80  	sf, err := findSockFile(c.Arg(0))
    81  	if err != nil {
    82  		c.SetError(err)
    83  		return
    84  	}
    85  	fd, err := sf.Accept4(c.Arg(1), c.Arg(2), c.Arg(3))
    86  	if err != nil {
    87  		c.SetError(err)
    88  		return
    89  	}
    90  	c.SetRet(uintptr(fd))
    91  
    92  }
    93  
    94  func sysConnect(c *isyscall.Request) {
    95  	sf, err := findSockFile(c.Arg(0))
    96  	if err != nil {
    97  		c.SetError(err)
    98  		return
    99  	}
   100  	uaddr := c.Arg(1)
   101  	uaddrlen := c.Arg(2)
   102  	err = sf.Connect(uaddr, uaddrlen)
   103  	c.SetError(err)
   104  }
   105  
   106  func sysSetsockopt(c *isyscall.Request) {
   107  	sf, err := findSockFile(c.Arg(0))
   108  	if err != nil {
   109  		c.SetError(err)
   110  		return
   111  	}
   112  	err = sf.Setsockopt(c.Arg(1), c.Arg(2), c.Arg(3), c.Arg(4))
   113  	// if err != nil {
   114  	// 	err = isyscall.EPANIC
   115  	// }
   116  	c.SetError(err)
   117  }
   118  
   119  func sysGetsockopt(c *isyscall.Request) {
   120  	sf, err := findSockFile(c.Arg(0))
   121  	if err != nil {
   122  		c.SetError(err)
   123  		return
   124  	}
   125  	err = sf.Getsockopt(c.Arg(1), c.Arg(2), c.Arg(3), c.Arg(4))
   126  	if err != nil {
   127  		c.SetError(err)
   128  		return
   129  	}
   130  	c.SetRet(0)
   131  }
   132  
   133  func sysGetsockname(c *isyscall.Request) {
   134  	sf, err := findSockFile(c.Arg(0))
   135  	if err != nil {
   136  		c.SetError(err)
   137  		return
   138  	}
   139  	err = sf.Getsockname(c.Arg(1), c.Arg(2))
   140  	// if err != nil {
   141  	// 	err = isyscall.EPANIC
   142  	// }
   143  	c.SetError(err)
   144  }
   145  
   146  func sysGetpeername(c *isyscall.Request) {
   147  	sf, err := findSockFile(c.Arg(0))
   148  	if err != nil {
   149  		c.SetError(err)
   150  		return
   151  	}
   152  	err = sf.Getpeername(c.Arg(1), c.Arg(2))
   153  	// if err != nil {
   154  	// 	err = isyscall.EPANIC
   155  	// }
   156  	c.SetError(err)
   157  }
   158  
   159  func ntohs(n uint16) uint16 {
   160  	return (n >> 8 & 0xff) | (n&0xff)<<8
   161  }
   162  
   163  func htons(n uint16) uint16 {
   164  	return ntohs(n)
   165  }
   166  
   167  func init() {
   168  	isyscall.Register(syscall.SYS_SOCKET, sysSocket)
   169  	isyscall.Register(syscall.SYS_BIND, sysBind)
   170  	isyscall.Register(syscall.SYS_LISTEN, sysListen)
   171  	isyscall.Register(syscall.SYS_ACCEPT4, sysAccept4)
   172  	isyscall.Register(syscall.SYS_CONNECT, sysConnect)
   173  	isyscall.Register(syscall.SYS_SETSOCKOPT, sysSetsockopt)
   174  	isyscall.Register(syscall.SYS_GETSOCKOPT, sysGetsockopt)
   175  	isyscall.Register(syscall.SYS_GETSOCKNAME, sysGetsockname)
   176  	isyscall.Register(syscall.SYS_GETPEERNAME, sysGetpeername)
   177  }