...
Run Format

Source file src/net/udpsock_posix.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	// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
     6	
     7	package net
     8	
     9	import (
    10		"context"
    11		"syscall"
    12	)
    13	
    14	func sockaddrToUDP(sa syscall.Sockaddr) Addr {
    15		switch sa := sa.(type) {
    16		case *syscall.SockaddrInet4:
    17			return &UDPAddr{IP: sa.Addr[0:], Port: sa.Port}
    18		case *syscall.SockaddrInet6:
    19			return &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
    20		}
    21		return nil
    22	}
    23	
    24	func (a *UDPAddr) family() int {
    25		if a == nil || len(a.IP) <= IPv4len {
    26			return syscall.AF_INET
    27		}
    28		if a.IP.To4() != nil {
    29			return syscall.AF_INET
    30		}
    31		return syscall.AF_INET6
    32	}
    33	
    34	func (a *UDPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
    35		if a == nil {
    36			return nil, nil
    37		}
    38		return ipToSockaddr(family, a.IP, a.Port, a.Zone)
    39	}
    40	
    41	func (c *UDPConn) readFrom(b []byte) (int, *UDPAddr, error) {
    42		var addr *UDPAddr
    43		n, sa, err := c.fd.readFrom(b)
    44		switch sa := sa.(type) {
    45		case *syscall.SockaddrInet4:
    46			addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port}
    47		case *syscall.SockaddrInet6:
    48			addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
    49		}
    50		return n, addr, err
    51	}
    52	
    53	func (c *UDPConn) readMsg(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
    54		var sa syscall.Sockaddr
    55		n, oobn, flags, sa, err = c.fd.readMsg(b, oob)
    56		switch sa := sa.(type) {
    57		case *syscall.SockaddrInet4:
    58			addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port}
    59		case *syscall.SockaddrInet6:
    60			addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
    61		}
    62		return
    63	}
    64	
    65	func (c *UDPConn) writeTo(b []byte, addr *UDPAddr) (int, error) {
    66		if c.fd.isConnected {
    67			return 0, ErrWriteToConnected
    68		}
    69		if addr == nil {
    70			return 0, errMissingAddress
    71		}
    72		sa, err := addr.sockaddr(c.fd.family)
    73		if err != nil {
    74			return 0, err
    75		}
    76		return c.fd.writeTo(b, sa)
    77	}
    78	
    79	func (c *UDPConn) writeMsg(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
    80		if c.fd.isConnected && addr != nil {
    81			return 0, 0, ErrWriteToConnected
    82		}
    83		if !c.fd.isConnected && addr == nil {
    84			return 0, 0, errMissingAddress
    85		}
    86		sa, err := addr.sockaddr(c.fd.family)
    87		if err != nil {
    88			return 0, 0, err
    89		}
    90		return c.fd.writeMsg(b, oob, sa)
    91	}
    92	
    93	func dialUDP(ctx context.Context, net string, laddr, raddr *UDPAddr) (*UDPConn, error) {
    94		fd, err := internetSocket(ctx, net, laddr, raddr, syscall.SOCK_DGRAM, 0, "dial")
    95		if err != nil {
    96			return nil, err
    97		}
    98		return newUDPConn(fd), nil
    99	}
   100	
   101	func listenUDP(ctx context.Context, network string, laddr *UDPAddr) (*UDPConn, error) {
   102		fd, err := internetSocket(ctx, network, laddr, nil, syscall.SOCK_DGRAM, 0, "listen")
   103		if err != nil {
   104			return nil, err
   105		}
   106		return newUDPConn(fd), nil
   107	}
   108	
   109	func listenMulticastUDP(ctx context.Context, network string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
   110		fd, err := internetSocket(ctx, network, gaddr, nil, syscall.SOCK_DGRAM, 0, "listen")
   111		if err != nil {
   112			return nil, err
   113		}
   114		c := newUDPConn(fd)
   115		if ip4 := gaddr.IP.To4(); ip4 != nil {
   116			if err := listenIPv4MulticastUDP(c, ifi, ip4); err != nil {
   117				c.Close()
   118				return nil, err
   119			}
   120		} else {
   121			if err := listenIPv6MulticastUDP(c, ifi, gaddr.IP); err != nil {
   122				c.Close()
   123				return nil, err
   124			}
   125		}
   126		return c, nil
   127	}
   128	
   129	func listenIPv4MulticastUDP(c *UDPConn, ifi *Interface, ip IP) error {
   130		if ifi != nil {
   131			if err := setIPv4MulticastInterface(c.fd, ifi); err != nil {
   132				return err
   133			}
   134		}
   135		if err := setIPv4MulticastLoopback(c.fd, false); err != nil {
   136			return err
   137		}
   138		if err := joinIPv4Group(c.fd, ifi, ip); err != nil {
   139			return err
   140		}
   141		return nil
   142	}
   143	
   144	func listenIPv6MulticastUDP(c *UDPConn, ifi *Interface, ip IP) error {
   145		if ifi != nil {
   146			if err := setIPv6MulticastInterface(c.fd, ifi); err != nil {
   147				return err
   148			}
   149		}
   150		if err := setIPv6MulticastLoopback(c.fd, false); err != nil {
   151			return err
   152		}
   153		if err := joinIPv6Group(c.fd, ifi, ip); err != nil {
   154			return err
   155		}
   156		return nil
   157	}
   158	

View as plain text