|
@@ -8,6 +8,7 @@ import (
|
|
|
"log"
|
|
|
"math"
|
|
|
"net"
|
|
|
+ "net/netip"
|
|
|
"os"
|
|
|
"strings"
|
|
|
"sync"
|
|
@@ -153,24 +154,48 @@ func New(config *config.C) (*Service, error) {
|
|
|
return &s, nil
|
|
|
}
|
|
|
|
|
|
-// DialContext dials the provided address. Currently only TCP is supported.
|
|
|
-func (s *Service) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
|
|
- if network != "tcp" && network != "tcp4" {
|
|
|
- return nil, errors.New("only tcp is supported")
|
|
|
- }
|
|
|
-
|
|
|
- addr, err := net.ResolveTCPAddr(network, address)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
+func getProtocolNumber(addr netip.Addr) tcpip.NetworkProtocolNumber {
|
|
|
+ if addr.Is6() {
|
|
|
+ return ipv6.ProtocolNumber
|
|
|
}
|
|
|
+ return ipv4.ProtocolNumber
|
|
|
+}
|
|
|
|
|
|
- fullAddr := tcpip.FullAddress{
|
|
|
- NIC: nicID,
|
|
|
- Addr: tcpip.AddrFromSlice(addr.IP),
|
|
|
- Port: uint16(addr.Port),
|
|
|
+// DialContext dials the provided address.
|
|
|
+func (s *Service) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
|
|
+ switch network {
|
|
|
+ case "udp", "udp4", "udp6":
|
|
|
+ addr, err := net.ResolveUDPAddr(network, address)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ fullAddr := tcpip.FullAddress{
|
|
|
+ NIC: nicID,
|
|
|
+ Addr: tcpip.AddrFromSlice(addr.IP),
|
|
|
+ Port: uint16(addr.Port),
|
|
|
+ }
|
|
|
+ num := getProtocolNumber(addr.AddrPort().Addr())
|
|
|
+ return gonet.DialUDP(s.ipstack, nil, &fullAddr, num)
|
|
|
+ case "tcp", "tcp4", "tcp6":
|
|
|
+ addr, err := net.ResolveTCPAddr(network, address)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ fullAddr := tcpip.FullAddress{
|
|
|
+ NIC: nicID,
|
|
|
+ Addr: tcpip.AddrFromSlice(addr.IP),
|
|
|
+ Port: uint16(addr.Port),
|
|
|
+ }
|
|
|
+ num := getProtocolNumber(addr.AddrPort().Addr())
|
|
|
+ return gonet.DialContextTCP(ctx, s.ipstack, fullAddr, num)
|
|
|
+ default:
|
|
|
+ return nil, fmt.Errorf("unknown network type: %s", network)
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- return gonet.DialContextTCP(ctx, s.ipstack, fullAddr, ipv4.ProtocolNumber)
|
|
|
+// Dial dials the provided address
|
|
|
+func (s *Service) Dial(network, address string) (net.Conn, error) {
|
|
|
+ return s.DialContext(context.Background(), network, address)
|
|
|
}
|
|
|
|
|
|
// Listen listens on the provided address. Currently only TCP with wildcard
|