...

Source file src/net/udpsock_plan9.go

     1	// Copyright 2009 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	package net
     6	
     7	import (
     8		"context"
     9		"errors"
    10		"os"
    11		"syscall"
    12	)
    13	
    14	func (c *UDPConn) readFrom(b []byte) (n int, addr *UDPAddr, err error) {
    15		buf := make([]byte, udpHeaderSize+len(b))
    16		m, err := c.fd.Read(buf)
    17		if err != nil {
    18			return 0, nil, err
    19		}
    20		if m < udpHeaderSize {
    21			return 0, nil, errors.New("short read reading UDP header")
    22		}
    23		buf = buf[:m]
    24	
    25		h, buf := unmarshalUDPHeader(buf)
    26		n = copy(b, buf)
    27		return n, &UDPAddr{IP: h.raddr, Port: int(h.rport)}, nil
    28	}
    29	
    30	func (c *UDPConn) readMsg(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
    31		return 0, 0, 0, nil, syscall.EPLAN9
    32	}
    33	
    34	func (c *UDPConn) writeTo(b []byte, addr *UDPAddr) (int, error) {
    35		if addr == nil {
    36			return 0, errMissingAddress
    37		}
    38		h := new(udpHeader)
    39		h.raddr = addr.IP.To16()
    40		h.laddr = c.fd.laddr.(*UDPAddr).IP.To16()
    41		h.ifcaddr = IPv6zero // ignored (receive only)
    42		h.rport = uint16(addr.Port)
    43		h.lport = uint16(c.fd.laddr.(*UDPAddr).Port)
    44	
    45		buf := make([]byte, udpHeaderSize+len(b))
    46		i := copy(buf, h.Bytes())
    47		copy(buf[i:], b)
    48		if _, err := c.fd.Write(buf); err != nil {
    49			return 0, err
    50		}
    51		return len(b), nil
    52	}
    53	
    54	func (c *UDPConn) writeMsg(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
    55		return 0, 0, syscall.EPLAN9
    56	}
    57	
    58	func (sd *sysDialer) dialUDP(ctx context.Context, laddr, raddr *UDPAddr) (*UDPConn, error) {
    59		fd, err := dialPlan9(ctx, sd.network, laddr, raddr)
    60		if err != nil {
    61			return nil, err
    62		}
    63		return newUDPConn(fd), nil
    64	}
    65	
    66	const udpHeaderSize = 16*3 + 2*2
    67	
    68	type udpHeader struct {
    69		raddr, laddr, ifcaddr IP
    70		rport, lport          uint16
    71	}
    72	
    73	func (h *udpHeader) Bytes() []byte {
    74		b := make([]byte, udpHeaderSize)
    75		i := 0
    76		i += copy(b[i:i+16], h.raddr)
    77		i += copy(b[i:i+16], h.laddr)
    78		i += copy(b[i:i+16], h.ifcaddr)
    79		b[i], b[i+1], i = byte(h.rport>>8), byte(h.rport), i+2
    80		b[i], b[i+1], i = byte(h.lport>>8), byte(h.lport), i+2
    81		return b
    82	}
    83	
    84	func unmarshalUDPHeader(b []byte) (*udpHeader, []byte) {
    85		h := new(udpHeader)
    86		h.raddr, b = IP(b[:16]), b[16:]
    87		h.laddr, b = IP(b[:16]), b[16:]
    88		h.ifcaddr, b = IP(b[:16]), b[16:]
    89		h.rport, b = uint16(b[0])<<8|uint16(b[1]), b[2:]
    90		h.lport, b = uint16(b[0])<<8|uint16(b[1]), b[2:]
    91		return h, b
    92	}
    93	
    94	func (sl *sysListener) listenUDP(ctx context.Context, laddr *UDPAddr) (*UDPConn, error) {
    95		l, err := listenPlan9(ctx, sl.network, laddr)
    96		if err != nil {
    97			return nil, err
    98		}
    99		_, err = l.ctl.WriteString("headers")
   100		if err != nil {
   101			return nil, err
   102		}
   103		l.data, err = os.OpenFile(l.dir+"/data", os.O_RDWR, 0)
   104		if err != nil {
   105			return nil, err
   106		}
   107		fd, err := l.netFD()
   108		return newUDPConn(fd), err
   109	}
   110	
   111	func (sl *sysListener) listenMulticastUDP(ctx context.Context, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
   112		l, err := listenPlan9(ctx, sl.network, gaddr)
   113		if err != nil {
   114			return nil, err
   115		}
   116		_, err = l.ctl.WriteString("headers")
   117		if err != nil {
   118			return nil, err
   119		}
   120		var addrs []Addr
   121		if ifi != nil {
   122			addrs, err = ifi.Addrs()
   123			if err != nil {
   124				return nil, err
   125			}
   126		} else {
   127			addrs, err = InterfaceAddrs()
   128			if err != nil {
   129				return nil, err
   130			}
   131		}
   132		for _, addr := range addrs {
   133			if ipnet, ok := addr.(*IPNet); ok {
   134				_, err = l.ctl.WriteString("addmulti " + ipnet.IP.String() + " " + gaddr.IP.String())
   135				if err != nil {
   136					return nil, err
   137				}
   138			}
   139		}
   140		l.data, err = os.OpenFile(l.dir+"/data", os.O_RDWR, 0)
   141		if err != nil {
   142			return nil, err
   143		}
   144		fd, err := l.netFD()
   145		if err != nil {
   146			return nil, err
   147		}
   148		return newUDPConn(fd), nil
   149	}
   150	

View as plain text