mirror of
https://github.com/tinygo-org/net.git
synced 2026-08-15 00:43:39 +00:00
Add network device driver model, netdev
This PR adds a network device driver model called netdev. There will be a companion PR for TinyGo drivers to update the netdev drivers and network examples. This PR covers the core "net" package. An RFC for the work is here: #tinygo-org/drivers#487. Some things have changed from the RFC, but nothing major. The "net" package is a partial port of Go's "net" package, version 1.19.3. The src/net/README file has details on what is modified from Go's "net" package. Most "net" features are working as they would in normal Go. TCP/UDP/TLS protocol support is there. As well as HTTP client and server support. Standard Go network packages such as golang.org/x/net/websockets and Paho MQTT client work as-is. Other packages are likely to work as-is. Testing results are here (https://docs.google.com/spreadsheets/d/e/2PACX-1vT0cCjBvwXf9HJf6aJV2Sw198F2ief02gmbMV0sQocKT4y4RpfKv3dh6Jyew8lQW64FouZ8GwA2yjxI/pubhtml?gid=1013173032&single=true).
This commit is contained in:
committed by
deadprogram
parent
b46e2ec2ac
commit
693edae782
+154
@@ -0,0 +1,154 @@
|
||||
// TINYGO: The following is copied and modified from Go 1.19.3 official implementation.
|
||||
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// TLS low level connection and record layer
|
||||
|
||||
package net
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func DialTLS(addr string) (*TLSConn, error) {
|
||||
|
||||
host, sport, err := SplitHostPort(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
port, err := strconv.Atoi(sport)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if port == 0 {
|
||||
port = 443
|
||||
}
|
||||
|
||||
fd, err := netdev.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TLS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = netdev.Connect(fd, host, IP{}, port); err != nil {
|
||||
netdev.Close(fd)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &TLSConn{
|
||||
fd: fd,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// A TLSConn represents a secured connection.
|
||||
// It implements the net.Conn interface.
|
||||
type TLSConn struct {
|
||||
fd int
|
||||
readDeadline time.Time
|
||||
writeDeadline time.Time
|
||||
}
|
||||
|
||||
// Access to net.Conn methods.
|
||||
// Cannot just embed net.Conn because that would
|
||||
// export the struct field too.
|
||||
|
||||
// LocalAddr returns the local network address.
|
||||
func (c *TLSConn) LocalAddr() Addr {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoteAddr returns the remote network address.
|
||||
func (c *TLSConn) RemoteAddr() Addr {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetDeadline sets the read and write deadlines associated with the connection.
|
||||
// A zero value for t means Read and Write will not time out.
|
||||
// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
|
||||
func (c *TLSConn) SetDeadline(t time.Time) error {
|
||||
c.readDeadline = t
|
||||
c.writeDeadline = t
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetReadDeadline sets the read deadline on the underlying connection.
|
||||
// A zero value for t means Read will not time out.
|
||||
func (c *TLSConn) SetReadDeadline(t time.Time) error {
|
||||
c.readDeadline = t
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetWriteDeadline sets the write deadline on the underlying connection.
|
||||
// A zero value for t means Write will not time out.
|
||||
// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
|
||||
func (c *TLSConn) SetWriteDeadline(t time.Time) error {
|
||||
c.writeDeadline = t
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *TLSConn) Read(b []byte) (int, error) {
|
||||
var timeout time.Duration
|
||||
|
||||
now := time.Now()
|
||||
|
||||
if !c.readDeadline.IsZero() {
|
||||
if c.readDeadline.Before(now) {
|
||||
return 0, fmt.Errorf("Read deadline expired")
|
||||
} else {
|
||||
timeout = c.readDeadline.Sub(now)
|
||||
}
|
||||
}
|
||||
|
||||
n, err := netdev.Recv(c.fd, b, 0, timeout)
|
||||
// Turn the -1 socket error into 0 and let err speak for error
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (c *TLSConn) Write(b []byte) (int, error) {
|
||||
var timeout time.Duration
|
||||
|
||||
now := time.Now()
|
||||
|
||||
if !c.writeDeadline.IsZero() {
|
||||
if c.writeDeadline.Before(now) {
|
||||
return 0, fmt.Errorf("Write deadline expired")
|
||||
} else {
|
||||
timeout = c.writeDeadline.Sub(now)
|
||||
}
|
||||
}
|
||||
|
||||
n, err := netdev.Send(c.fd, b, 0, timeout)
|
||||
// Turn the -1 socket error into 0 and let err speak for error
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (c *TLSConn) Close() error {
|
||||
return netdev.Close(c.fd)
|
||||
}
|
||||
|
||||
// Handshake runs the client or server handshake
|
||||
// protocol if it has not yet been run.
|
||||
//
|
||||
// Most uses of this package need not call Handshake explicitly: the
|
||||
// first Read or Write will call it automatically.
|
||||
//
|
||||
// For control over canceling or setting a timeout on a handshake, use
|
||||
// HandshakeContext or the Dialer's DialContext method instead.
|
||||
func (c *TLSConn) Handshake() error {
|
||||
panic("TLSConn.Handshake() not implemented")
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user