123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- package portmapper
- import (
- "fmt"
- "io"
- "net"
- "github.com/ishidawataru/sctp"
- )
- type userlandProxy interface {
- Start() error
- Stop() error
- }
- // ipVersion refers to IP version - v4 or v6
- type ipVersion string
- const (
- // IPv4 is version 4
- ipv4 ipVersion = "4"
- // IPv4 is version 6
- ipv6 ipVersion = "6"
- )
- // dummyProxy just listen on some port, it is needed to prevent accidental
- // port allocations on bound port, because without userland proxy we using
- // iptables rules and not net.Listen
- type dummyProxy struct {
- listener io.Closer
- addr net.Addr
- ipVersion ipVersion
- }
- func newDummyProxy(proto string, hostIP net.IP, hostPort int) (userlandProxy, error) {
- // detect version of hostIP to bind only to correct version
- version := ipv4
- if hostIP.To4() == nil {
- version = ipv6
- }
- switch proto {
- case "tcp":
- addr := &net.TCPAddr{IP: hostIP, Port: hostPort}
- return &dummyProxy{addr: addr, ipVersion: version}, nil
- case "udp":
- addr := &net.UDPAddr{IP: hostIP, Port: hostPort}
- return &dummyProxy{addr: addr, ipVersion: version}, nil
- case "sctp":
- addr := &sctp.SCTPAddr{IPAddrs: []net.IPAddr{{IP: hostIP}}, Port: hostPort}
- return &dummyProxy{addr: addr, ipVersion: version}, nil
- default:
- return nil, fmt.Errorf("Unknown addr type: %s", proto)
- }
- }
- func (p *dummyProxy) Start() error {
- switch addr := p.addr.(type) {
- case *net.TCPAddr:
- l, err := net.ListenTCP("tcp"+string(p.ipVersion), addr)
- if err != nil {
- return err
- }
- p.listener = l
- case *net.UDPAddr:
- l, err := net.ListenUDP("udp"+string(p.ipVersion), addr)
- if err != nil {
- return err
- }
- p.listener = l
- case *sctp.SCTPAddr:
- l, err := sctp.ListenSCTP("sctp"+string(p.ipVersion), addr)
- if err != nil {
- return err
- }
- p.listener = l
- default:
- return fmt.Errorf("Unknown addr type: %T", p.addr)
- }
- return nil
- }
- func (p *dummyProxy) Stop() error {
- if p.listener != nil {
- return p.listener.Close()
- }
- return nil
- }
|