blob: 831f2a35d5ae948be3880194e80a148fd9f27199 [file] [log] [blame]
// Copyright 2016 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.
//+build fuchsia
package net
import (
"context"
"syscall"
"syscall/zx/net"
"syscall/zx/posix/socket"
)
func (a *UDPAddr) domain() socket.Domain {
if a == nil || len(a.IP) <= IPv4len {
return socket.DomainIpv4
}
if a.IP.To4() != nil {
return socket.DomainIpv4
}
return socket.DomainIpv6
}
func (a *UDPAddr) family() int {
return domainToFamily(a.domain())
}
func (a *UDPAddr) sockaddr(domain socket.Domain) (addr net.SocketAddress, err error) {
if a == nil {
return net.SocketAddressWithIpv4(net.Ipv4SocketAddress{}), nil
}
return ipToSockaddr(domain, a.IP, a.Port, a.Zone)
}
func (c *UDPConn) readFrom(b []byte) (n int, addr *UDPAddr, err error) {
n, _, _, addr, err = c.readMsg(b, nil)
return n, addr, err
}
func (c *UDPConn) readMsg(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
n, flags, address, err := c.fd.readMsg(b)
if err != nil {
return 0, 0, 0, nil, err
}
ip, port := socketAddrToIpPort(address)
addr = &UDPAddr{
IP: ip,
Port: port,
}
return n, 0, flags, addr, nil
}
func (c *UDPConn) writeTo(b []byte, addr *UDPAddr) (int, error) {
n, _, err := c.writeMsg(b, nil, addr)
return n, err
}
func (c *UDPConn) writeMsg(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
if c.fd.isConnected && addr != nil {
return 0, 0, ErrWriteToConnected
}
if !c.fd.isConnected && addr == nil {
return 0, 0, errMissingAddress
}
if len(oob) > 0 {
return 0, 0, syscall.EFUCHSIA
}
if addr == nil {
n, err = c.fd.Write(b)
return n, 0, err
}
{
addr, err := addr.sockaddr(familyToDomain(c.fd.family))
if err != nil {
return 0, 0, err
}
n, err = c.fd.sendMsg(b, addr)
return n, 0, err
}
}
func (sd *sysDialer) dialUDP(ctx context.Context, laddr, raddr *UDPAddr) (*UDPConn, error) {
switch sd.network {
case "udp", "udp4", "udp6":
default:
return nil, UnknownNetworkError(sd.network)
}
if raddr == nil {
return nil, errMissingAddress
}
var laddrif sockaddr
if laddr != nil {
laddrif = laddr
}
fd, err := dialFuchsia(ctx, sd.network, laddrif, raddr)
if err != nil {
return nil, err
}
return newUDPConn(fd), nil
}
func (sl *sysListener) listenUDP(ctx context.Context, laddr *UDPAddr) (*UDPConn, error) {
var laddrif sockaddr
if laddr != nil {
laddrif = laddr
}
fd, err := dialFuchsia(ctx, sl.network, laddrif, nil)
if err != nil {
return nil, err
}
return newUDPConn(fd), nil
}
func (sl *sysListener) listenMulticastUDP(ctx context.Context, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
return nil, syscall.EFUCHSIA
}