github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/runtime/ppapi/network_nacl.go (about) 1 // Copyright 2014 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 ppapi 6 7 import ( 8 "encoding/binary" 9 "errors" 10 "fmt" 11 "io" 12 "net" 13 "strconv" 14 "strings" 15 "time" 16 "unsafe" 17 ) 18 19 var ( 20 errCreateAddressFailed = errors.New("CreateAddress failed") 21 errMalformedAddress = errors.New("malformed network address") 22 errLocalAddrFailed = errors.New("LocalAddr failed") 23 errRemoteAddrFailed = errors.New("RemoteAddr failed") 24 errDeadlineNotSupported = errors.New("deadlines are not supported") 25 errCreateTCPSocketFailed = errors.New("could not create TCP socket") 26 errCreateUDPSocketFailed = errors.New("could not create UDP socket") 27 errNotConnected = errors.New("not connected") 28 errCreateHostResolverFailed = errors.New("CreateHostResolver failed") 29 errCanonicalNameFailed = errors.New("CanonicalName failed") 30 errCanonNameFlagNotSet = errors.New("PP_HOSTRESOLVER_FLAG_CANONNAME not set in HostResolverHint") 31 errHostResolverFailed = errors.New("host resolution failed") 32 ) 33 34 // HostResolver supports host name resolution. 35 // 36 // It isn't normally necessary to use the HostResolver directly, since the Dial 37 // and Listen methods perform host resolution automatically. 38 type HostResolver struct { 39 Resource 40 } 41 42 // HostResolveHint represents hints for host resolution. 43 type HostResolverHint struct { 44 Family NetAddressFamily 45 Flags int32 46 } 47 48 // CreateHostResolver creates a HostResolver. 49 func (inst Instance) CreateHostResolver() (resolver HostResolver, err error) { 50 resolver.id = ppb_hostresolver_create(inst.id) 51 if resolver.id == 0 { 52 err = errCreateHostResolverFailed 53 } 54 return 55 } 56 57 // Resolve requests resolution of a host name. 58 // 59 // If the call completes successfully, the results can be retrieved by 60 // CanonicalName(), NetAddressCount() and NetAddress(). 61 func (resolver HostResolver) Resolve(host string, port uint16, hint *HostResolverHint) error { 62 name := append([]byte(host), 0) 63 code := ppb_hostresolver_resolve( 64 resolver.id, &name[0], port, 65 (*pp_HostResolverHint)(unsafe.Pointer(hint)), ppNullCompletionCallback) 66 return decodeError(Error(code)) 67 } 68 69 // CanonicalName gets the canonical name of the host. 70 func (resolver HostResolver) GetCanonicalName() (s string, err error) { 71 var ppVar pp_Var 72 ppb_hostresolver_get_canonical_name(&ppVar, resolver.id) 73 var v Var 74 v.fromPP(ppVar) 75 s, err = v.AsString() 76 if err != nil { 77 err = errCanonicalNameFailed 78 return 79 } 80 if s == "" { 81 err = errCanonNameFlagNotSet 82 return 83 } 84 return 85 } 86 87 // NetAddresses returns the resolved network addresses. 88 func (resolver HostResolver) NetAddresses() []NetAddress { 89 count := ppb_hostresolver_get_net_address_count(resolver.id) 90 var addresses []NetAddress 91 for i := uint32(0); i != count; i++ { 92 var addr NetAddress 93 addr.id = ppb_hostresolver_get_net_address(resolver.id, i) 94 if addr.id != 0 { 95 addresses = append(addresses, addr) 96 } 97 } 98 return addresses 99 } 100 101 // ResolveNetAddress resolves a network address. 102 func (inst Instance) ResolveNetAddress(network, addr string) (na NetAddress, err error) { 103 if strings.HasPrefix(addr, "[::]:") { 104 // TODO(bprosnitz) We really shouldn't have to do this. Chrome won't resolve the IPv6 105 // address for some reason. Fix this. 106 addr = strings.Replace(addr, "[::]:", "127.0.0.1:", 1) 107 } 108 host, strport, err := net.SplitHostPort(addr) 109 if err != nil { 110 panic(fmt.Sprintf("Failed to resolve 1 %s: %s", addr, err)) 111 return 112 } 113 port, err := strconv.Atoi(strport) 114 if err != nil { 115 panic(fmt.Sprintf("Failed to resolve 2 %s: %s", addr, err)) 116 117 return 118 } 119 var hint HostResolverHint 120 switch network { 121 case "tcp", "udp": 122 hint.Family = PP_NETADDRESS_FAMILY_UNSPECIFIED 123 case "tcp4", "udp4": 124 hint.Family = PP_NETADDRESS_FAMILY_IPV4 125 case "tcp6", "udp6": 126 hint.Family = PP_NETADDRESS_FAMILY_IPV6 127 default: 128 err = fmt.Errorf("unsupported network: %q", network) 129 return 130 } 131 resolver, err := inst.CreateHostResolver() 132 if err != nil { 133 panic(fmt.Sprintf("Failed to resolve 3 %s: %s", addr, err)) 134 135 return 136 } 137 defer resolver.Release() 138 if err = resolver.Resolve(host, uint16(port), &hint); err != nil { 139 panic(fmt.Sprintf("Failed to resolve 4 %s: %s", addr, err)) 140 return 141 } 142 addrs := resolver.NetAddresses() 143 if len(addrs) == 0 { 144 err = errHostResolverFailed 145 panic(fmt.Sprintf("Failed to resolve 5 %s: %s", addr, err)) 146 return 147 } 148 for _, addr := range addrs[1:] { 149 addr.Release() 150 } 151 na = addrs[0] 152 return 153 } 154 155 // ResolveTCPAddr parses addr as a TCP address of the form "host:port" or 156 // "[ipv6-host%zone]:port" and resolves a pair of domain name and port name on 157 // the network net, which must be "tcp", "tcp4" or "tcp6". A literal address or 158 // host name for IPv6 must be enclosed in square brackets, as in "[::1]:80", 159 // "[ipv6-host]:http" or "[ipv6-host%zone]:80". 160 func (inst Instance) ResolveTCPAddr(network, addr string) (*net.TCPAddr, error) { 161 na, err := inst.ResolveNetAddress(network, addr) 162 if err != nil { 163 return nil, err 164 } 165 defer na.Release() 166 return na.TCPAddr() 167 } 168 169 // ResolveUDPAddr parses addr as a UDP address of the form "host:port" or 170 // "[ipv6-host%zone]:port" and resolves a pair of domain name and port name on 171 // the network net, which must be "udp", "udp4" or "udp6". A literal address or 172 // host name for IPv6 must be enclosed in square brackets, as in "[::1]:80", 173 // "[ipv6-host]:http" or "[ipv6-host%zone]:80". 174 func (inst Instance) ResolveUDPAddr(network, addr string) (*net.UDPAddr, error) { 175 na, err := inst.ResolveNetAddress(network, addr) 176 if err != nil { 177 return nil, err 178 } 179 defer na.Release() 180 return na.UDPAddr() 181 } 182 183 // NetAddress represents a network address. 184 type NetAddress struct { 185 Resource 186 } 187 188 // createTCPAddress creates an address from a net.TCPAddr. 189 func (inst Instance) CreateTCPNetAddress(net string, addr *net.TCPAddr) (na NetAddress, err error) { 190 if net == "tcp" || net == "tcp4" { 191 if ipv4 := addr.IP.To4(); ipv4 != nil { 192 var ppNetAddress pp_NetAddress_IPv4 193 binary.BigEndian.PutUint16(ppNetAddress[0:2], uint16(addr.Port)) 194 copy(ppNetAddress[2:6], ipv4) 195 na.id = ppb_netaddress_create_from_ipv4_address(inst.id, &ppNetAddress) 196 if na.id == 0 { 197 err = errCreateAddressFailed 198 } 199 return 200 } 201 } 202 203 if net == "tcp" || net == "tcp6" { 204 if ipv6 := addr.IP.To16(); ipv6 != nil { 205 var ppNetAddress pp_NetAddress_IPv6 206 binary.BigEndian.PutUint16(ppNetAddress[0:2], uint16(addr.Port)) 207 copy(ppNetAddress[2:18], ipv6) 208 na.id = ppb_netaddress_create_from_ipv6_address(inst.id, &ppNetAddress) 209 if na.id == 0 { 210 err = errCreateAddressFailed 211 } 212 return 213 } 214 } 215 216 err = errMalformedAddress 217 return 218 } 219 220 // decodeTCPAddress returns the TCP address. 221 func (na NetAddress) TCPAddr() (addr *net.TCPAddr, err error) { 222 family := ppb_netaddress_get_family(na.id) 223 switch family { 224 case PP_NETADDRESS_FAMILY_UNSPECIFIED: 225 err = errMalformedAddress 226 case PP_NETADDRESS_FAMILY_IPV4: 227 var ipv4 pp_NetAddress_IPv4 228 if ok := ppb_netaddress_describe_as_ipv4_address(na.id, &ipv4); ok == ppFalse { 229 err = errMalformedAddress 230 return 231 } 232 addr = &net.TCPAddr{Port: int(binary.BigEndian.Uint16(ipv4[0:2])), IP: make([]byte, 4)} 233 copy(addr.IP, ipv4[2:6]) 234 case PP_NETADDRESS_FAMILY_IPV6: 235 var ipv6 pp_NetAddress_IPv6 236 if ok := ppb_netaddress_describe_as_ipv6_address(na.id, &ipv6); ok == ppFalse { 237 err = errMalformedAddress 238 return 239 } 240 addr = &net.TCPAddr{Port: int(binary.BigEndian.Uint16(ipv6[0:2])), IP: make([]byte, 16)} 241 copy(addr.IP, ipv6[2:18]) 242 } 243 return 244 } 245 246 // createUDPAddress creates an address from a net.UDPAddr. 247 func (inst Instance) CreateUDPNetAddress(net string, addr *net.UDPAddr) (na NetAddress, err error) { 248 if net == "udp" || net == "udp4" { 249 if ipv4 := addr.IP.To4(); ipv4 != nil { 250 var ppNetAddress pp_NetAddress_IPv4 251 binary.BigEndian.PutUint16(ppNetAddress[0:2], uint16(addr.Port)) 252 copy(ppNetAddress[2:6], ipv4) 253 na.id = ppb_netaddress_create_from_ipv4_address(inst.id, &ppNetAddress) 254 if na.id == 0 { 255 err = errCreateAddressFailed 256 } 257 return 258 } 259 } 260 261 if net == "udp" || net == "udp6" { 262 if ipv6 := addr.IP.To16(); ipv6 != nil { 263 var ppNetAddress pp_NetAddress_IPv6 264 binary.BigEndian.PutUint16(ppNetAddress[0:2], uint16(addr.Port)) 265 copy(ppNetAddress[2:18], ipv6) 266 na.id = ppb_netaddress_create_from_ipv6_address(inst.id, &ppNetAddress) 267 if na.id == 0 { 268 err = errCreateAddressFailed 269 } 270 return 271 } 272 } 273 274 err = errMalformedAddress 275 return 276 } 277 278 // decodeUDPAddress returns the UDP address. 279 func (na NetAddress) UDPAddr() (addr *net.UDPAddr, err error) { 280 family := ppb_netaddress_get_family(na.id) 281 switch family { 282 case PP_NETADDRESS_FAMILY_UNSPECIFIED: 283 err = errMalformedAddress 284 case PP_NETADDRESS_FAMILY_IPV4: 285 var ipv4 pp_NetAddress_IPv4 286 if ok := ppb_netaddress_describe_as_ipv4_address(na.id, &ipv4); ok == ppFalse { 287 err = errMalformedAddress 288 return 289 } 290 addr = &net.UDPAddr{Port: int(binary.BigEndian.Uint16(ipv4[0:2])), IP: make([]byte, 4)} 291 copy(addr.IP, ipv4[2:6]) 292 case PP_NETADDRESS_FAMILY_IPV6: 293 var ipv6 pp_NetAddress_IPv6 294 if ok := ppb_netaddress_describe_as_ipv6_address(na.id, &ipv6); ok == ppFalse { 295 err = errMalformedAddress 296 return 297 } 298 addr = &net.UDPAddr{Port: int(binary.BigEndian.Uint16(ipv6[0:2])), IP: make([]byte, 16)} 299 copy(addr.IP, ipv6[2:18]) 300 } 301 return 302 } 303 304 // tcpSocket implements functions common to both dialed and lister sockets. 305 type tcpSocket struct { 306 Resource 307 closed bool 308 } 309 310 // CreateTCPConn creates a fresh, unconnected socket. 311 // 312 // Permissions: Apps permission socket with subrule tcp-connect is required for 313 // Connect(); subrule tcp-listen is required for Listen(). For more details 314 // about network communication permissions, please see: 315 // http://developer.chrome.com/apps/app_network.html 316 func (inst Instance) createTCPConn() (s tcpSocket, err error) { 317 id := ppb_tcpsocket_create(inst.id) 318 if id == 0 { 319 err = errCreateTCPSocketFailed 320 return 321 } 322 s.id = id 323 return 324 } 325 326 // Bind the socket to an address. 327 func (sock *tcpSocket) bind(addr *NetAddress) error { 328 code := ppb_tcpsocket_bind(sock.id, addr.id, ppNullCompletionCallback) 329 return decodeError(Error(code)) 330 } 331 332 // Accept a connection. 333 func (sock *tcpSocket) accept() (accepted *TCPConn, err error) { 334 accepted = &TCPConn{} 335 code := ppb_tcpsocket_accept(sock.id, &accepted.id, ppNullCompletionCallback) 336 if Error(code) == PP_ERROR_ABORTED { 337 err = io.EOF 338 } else if code < 0 { 339 err = decodeError(Error(code)) 340 } 341 return 342 } 343 344 // Connects the socket to the given address. 345 // 346 // The socket must not be listening. Binding the socket beforehand is optional. 347 func (sock *tcpSocket) connect(addr *NetAddress) error { 348 code := ppb_tcpsocket_connect(sock.id, addr.id, ppNullCompletionCallback) 349 return decodeError(Error(code)) 350 } 351 352 // Starts listening. 353 // 354 // The socket must be bound and not connected. 355 func (sock *tcpSocket) listen(backlog int) error { 356 code := ppb_tcpsocket_listen(sock.id, int32(backlog), ppNullCompletionCallback) 357 return decodeError(Error(code)) 358 } 359 360 // localAddr returns the local address of the socket, if it is bound. 361 func (sock *tcpSocket) localAddr() net.Addr { 362 var local NetAddress 363 local.id = ppb_tcpsocket_get_local_address(sock.id) 364 if local.id == 0 { 365 return nil 366 } 367 defer local.Release() 368 369 tcpAddr, err := local.TCPAddr() 370 if err != nil { 371 return nil 372 } 373 return tcpAddr 374 } 375 376 // remoteAddr returns the remote address of the socket, if it is connected. 377 func (sock *tcpSocket) remoteAddr() net.Addr { 378 var local NetAddress 379 local.id = ppb_tcpsocket_get_remote_address(sock.id) 380 if local.id == 0 { 381 return nil 382 } 383 defer local.Release() 384 385 tcpAddr, err := local.TCPAddr() 386 if err != nil { 387 return nil 388 } 389 return tcpAddr 390 } 391 392 // TCPConn is a TCP socket. 393 type TCPConn struct { 394 tcpSocket 395 } 396 397 // DialTCP connects to the remote address raddr on the network net, which must be 398 // "tcp", "tcp4", or "tcp6". If laddr is not nil, it is used as the local 399 // address for the connection. 400 func (inst Instance) DialTCP(net string, laddr, raddr *net.TCPAddr) (conn *TCPConn, err error) { 401 conn = &TCPConn{} 402 conn.tcpSocket, err = inst.createTCPConn() 403 if err != nil { 404 return 405 } 406 if laddr != nil { 407 var addr NetAddress 408 addr, err = inst.CreateTCPNetAddress(net, laddr) 409 if err != nil { 410 conn.Release() 411 return 412 } 413 defer addr.Release() 414 if err = conn.bind(&addr); err != nil { 415 conn.Release() 416 return 417 } 418 } 419 var addr NetAddress 420 addr, err = inst.CreateTCPNetAddress(net, raddr) 421 if err != nil { 422 conn.Release() 423 return 424 } 425 defer addr.Release() 426 if err = conn.connect(&addr); err != nil { 427 conn.Release() 428 return 429 } 430 return 431 } 432 433 // Close closes the connection. 434 // 435 // Any pending callbacks will still run, reporting PP_ERROR_ABORTED if pending 436 // IO was interrupted. After a call to this method, no output buffer pointers 437 // passed into previous Read() or Accept() calls will be accessed. It is not 438 // valid to call Connect() or Listen() again. 439 func (conn *TCPConn) Close() error { 440 ppb_tcpsocket_close(conn.id) 441 conn.Release() 442 conn.closed = true 443 return nil 444 } 445 446 // localAddr returns the local address of the socket, if it is bound. 447 func (conn *TCPConn) LocalAddr() net.Addr { 448 return conn.localAddr() 449 } 450 451 // RemoteAddr returns the remote address of the socket, if it is connected. 452 func (conn *TCPConn) RemoteAddr() net.Addr { 453 return conn.remoteAddr() 454 } 455 456 // Read reads data from the connection. Deadlines are not supported. 457 func (conn *TCPConn) Read(buf []byte) (n int, err error) { 458 if conn.closed { 459 return 0, fmt.Errorf("Reading from closed connection") 460 } 461 code := ppb_tcpsocket_read(conn.id, &buf[0], int32(len(buf)), ppNullCompletionCallback) 462 if code < 0 { 463 err = decodeError(Error(code)) 464 return 465 } 466 if code == 0 { 467 err = io.EOF 468 return 469 } 470 n = int(code) 471 return 472 } 473 474 // Write writes data to the connection. Deadlines are not supported. 475 func (conn *TCPConn) Write(buf []byte) (n int, err error) { 476 if conn.closed { 477 return 0, fmt.Errorf("Writing to closed connection") 478 } 479 for len(buf) != 0 { 480 code := ppb_tcpsocket_write(conn.id, &buf[0], int32(len(buf)), ppNullCompletionCallback) 481 if code < 0 { 482 err = decodeError(Error(code)) 483 return 484 } 485 if code == 0 { 486 err = io.EOF 487 return 488 } 489 amount := int(code) 490 n += amount 491 buf = buf[amount:] 492 } 493 return 494 } 495 496 // SetReadBuffer sets the size of the operating system's receive buffer 497 // associated with the connection. 498 func (conn *TCPConn) SetReadBuffer(bytes int) error { 499 v := VarFromInt(int32(bytes)) 500 code := ppb_tcpsocket_set_option(conn.id, PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE, v.toPPVar(), ppNullCompletionCallback) 501 return decodeError(Error(code)) 502 } 503 504 // SetWriteBuffer sets the size of the operating system's receive buffer 505 // associated with the connection. 506 func (conn *TCPConn) SetWriteBuffer(bytes int) error { 507 v := VarFromInt(int32(bytes)) 508 code := ppb_tcpsocket_set_option(conn.id, PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE, v.toPPVar(), ppNullCompletionCallback) 509 return decodeError(Error(code)) 510 } 511 512 // SetDeadline sets the read and write deadlines associated 513 // with the connection. Not supported. 514 func (conn *TCPConn) SetDeadline(t time.Time) error { 515 return errDeadlineNotSupported 516 } 517 518 // SetReadDeadline sets the deadline for future Read calls. 519 // Not supported. 520 func (conn *TCPConn) SetReadDeadline(t time.Time) error { 521 return errDeadlineNotSupported 522 } 523 524 // SetWriteDeadline sets the deadline for future Write calls. 525 // Not supported. 526 func (conn *TCPConn) SetWriteDeadline(t time.Time) error { 527 return errDeadlineNotSupported 528 } 529 530 // TCPListener is a TCP network listener. 531 type TCPListener struct { 532 tcpSocket 533 } 534 535 // ListenTCP announces on the TCP address laddr and returns a TCP listener. Net 536 // must be "tcp", "tcp4", or "tcp6". If laddr has a port of 0, ListenTCP will 537 // choose an available port. The caller can use the Addr method of TCPListener 538 // to retrieve the chosen address. 539 func (inst Instance) ListenTCP(net string, laddr *net.TCPAddr) (l *TCPListener, err error) { 540 l = &TCPListener{} 541 l.tcpSocket, err = inst.createTCPConn() 542 if err != nil { 543 return 544 } 545 if laddr != nil { 546 var addr NetAddress 547 addr, err = inst.CreateTCPNetAddress(net, laddr) 548 if err != nil { 549 l.Release() 550 return 551 } 552 defer addr.Release() 553 if err = l.bind(&addr); err != nil { 554 l.Release() 555 return 556 } 557 } 558 // TODO(jyh): where does the backlog 5 come from? 559 if err = l.listen(5); err != nil { 560 l.Release() 561 return 562 } 563 return 564 } 565 566 // Accept implements the Accept method in the Listener interface; it waits for 567 // the next call and returns a generic Conn. 568 func (l *TCPListener) Accept() (net.Conn, error) { 569 return l.AcceptTCP() 570 } 571 572 // AcceptTCP accepts the next incoming call and returns the new connection. 573 func (l *TCPListener) AcceptTCP() (*TCPConn, error) { 574 return l.accept() 575 } 576 577 // Addr returns the listener's network address, a *TCPAddr. 578 func (l *TCPListener) Addr() net.Addr { 579 return l.localAddr() 580 } 581 582 // Close stops listening on the TCP address. Already accepted connections are 583 // not closed. 584 func (l *TCPListener) Close() error { 585 ppb_tcpsocket_close(l.id) 586 return nil 587 } 588 589 // UDPConn is the implementation of the Conn and PacketConn interfaces for UDP network connections. 590 type UDPConn struct { 591 Resource 592 inst Instance 593 net string 594 remoteAddr NetAddress 595 } 596 597 // Release the resources associated with the UDPConn. 598 func (conn *UDPConn) Release() { 599 conn.remoteAddr.Release() 600 conn.Resource.Release() 601 } 602 603 // DialUDP connects to the remote address raddr on the network net, which must 604 // be "udp", "udp4", or "udp6". If laddr is not nil, it is used as the local 605 // address for the connection. 606 func (inst Instance) DialUDP(net string, laddr, raddr *net.UDPAddr) (conn *UDPConn, err error) { 607 conn, err = inst.ListenUDP(net, laddr) 608 if err != nil { 609 return 610 } 611 conn.remoteAddr, err = inst.CreateUDPNetAddress(net, raddr) 612 if err != nil { 613 conn.Release() 614 return 615 } 616 return 617 } 618 619 // ListenUDP listens for incoming UDP packets addressed to the local address 620 // laddr. Net must be "udp", "udp4", or "udp6". If laddr has a port of 0, 621 // ListenUDP will choose an available port. The LocalAddr method of the returned 622 // UDPConn can be used to discover the port. The returned connection's ReadFrom 623 // and WriteTo methods can be used to receive and send UDP packets with 624 // per-packet addressing. 625 func (inst Instance) ListenUDP(net string, laddr *net.UDPAddr) (conn *UDPConn, err error) { 626 conn = &UDPConn{} 627 conn.inst = inst 628 conn.id = ppb_udpsocket_create(inst.id) 629 if conn.id == 0 { 630 err = errCreateUDPSocketFailed 631 return 632 } 633 if laddr != nil { 634 var addr NetAddress 635 addr, err = inst.CreateUDPNetAddress(net, laddr) 636 if err != nil { 637 conn.Release() 638 return 639 } 640 defer addr.Release() 641 code := ppb_udpsocket_bind(conn.id, addr.id, ppNullCompletionCallback) 642 if code < 0 { 643 conn.Release() 644 err = decodeError(Error(code)) 645 return 646 } 647 } 648 conn.net = net 649 return 650 } 651 652 // Close closes the connection. 653 func (conn *UDPConn) Close() error { 654 ppb_udpsocket_close(conn.id) 655 conn.Release() 656 return nil 657 } 658 659 // LocalAddr returns the local network address. 660 func (conn *UDPConn) LocalAddr() net.Addr { 661 var na NetAddress 662 na.id = ppb_udpsocket_get_bound_address(conn.id) 663 if na.id == 0 { 664 return nil 665 } 666 defer na.Release() 667 addr, _ := na.UDPAddr() 668 return addr 669 } 670 671 // RemoteAddr returns the remote network address. 672 func (conn *UDPConn) RemoteAddr() net.Addr { 673 addr, _ := conn.remoteAddr.UDPAddr() 674 return addr 675 } 676 677 // Read implements the net.Conn Read method. 678 func (conn *UDPConn) Read(buf []byte) (n int, err error) { 679 n, _, err = conn.ReadFrom(buf) 680 return 681 } 682 683 // ReadFrom implements the net.PacketConn ReadFrom method. 684 func (conn *UDPConn) ReadFrom(buf []byte) (n int, addr net.Addr, err error) { 685 n, addr, err = conn.ReadFromUDP(buf) 686 return 687 } 688 689 // ReadFromUDP reads a UDP packet from conn, copying the payload into buf. It 690 // returns the number of bytes copied into buf and the return address that was 691 // on the packet. 692 func (conn *UDPConn) ReadFromUDP(buf []byte) (n int, addr *net.UDPAddr, err error) { 693 var na NetAddress 694 defer na.Release() 695 code := ppb_udpsocket_recvfrom(conn.id, &buf[0], int32(len(buf)), &na.id, ppNullCompletionCallback) 696 if Error(code) == PP_ERROR_ABORTED { 697 err = io.EOF 698 } else if code < 0 { 699 err = decodeError(Error(code)) 700 return 701 } 702 n = int(code) 703 addr, _ = na.UDPAddr() 704 return 705 } 706 707 // Write implements the Conn Write method. 708 func (conn *UDPConn) Write(buf []byte) (int, error) { 709 return conn.WriteToAddress(buf, conn.remoteAddr) 710 } 711 712 // WriteTo implements the PacketConn WriteTo method. 713 func (conn *UDPConn) WriteTo(buf []byte, addr net.Addr) (int, error) { 714 na, err := conn.inst.ResolveNetAddress(addr.Network(), addr.String()) 715 if err != nil { 716 return 0, err 717 } 718 defer na.Release() 719 return conn.WriteToAddress(buf, na) 720 } 721 722 // WriteToUDP writes a UDP packet to addr via conn, copying the payload from buf. 723 func (conn *UDPConn) WriteToUDP(buf []byte, addr *net.UDPAddr) (int, error) { 724 na, err := conn.inst.CreateUDPNetAddress(conn.net, addr) 725 if err != nil { 726 return 0, err 727 } 728 defer na.Release() 729 return conn.WriteToAddress(buf, na) 730 } 731 732 // WriteToAddress writes a UDP packet to addr via conn, copying the payload from buf. 733 func (conn *UDPConn) WriteToAddress(buf []byte, na NetAddress) (n int, err error) { 734 code := ppb_udpsocket_sendto(conn.id, &buf[0], int32(len(buf)), na.id, ppNullCompletionCallback) 735 if code < 0 { 736 err = decodeError(Error(code)) 737 return 738 } 739 n = int(code) 740 return 741 } 742 743 // SetDeadline sets the read and write deadlines associated 744 // with the connection. Not supported. 745 func (conn *UDPConn) SetDeadline(t time.Time) error { 746 return errDeadlineNotSupported 747 } 748 749 // SetReadDeadline sets the deadline for future Read calls. 750 // Not supported. 751 func (conn *UDPConn) SetReadDeadline(t time.Time) error { 752 return errDeadlineNotSupported 753 } 754 755 // SetWriteDeadline sets the deadline for future Write calls. 756 // Not supported. 757 func (conn *UDPConn) SetWriteDeadline(t time.Time) error { 758 return errDeadlineNotSupported 759 } 760 761 // Dial connects to the address on the named network. 762 // 763 // Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only), "udp", 764 // "udp4" (IPv4-only), "udp6" (IPv6-only). 765 // 766 // For TCP and UDP networks, addresses have the form host:port. If host is a 767 // literal IPv6 address or host name, it must be enclosed in square brackets as 768 // in "[::1]:80" or "[ipv6-host%zone]:80". 769 func (inst Instance) Dial(network, address string) (net.Conn, error) { 770 switch network { 771 case "tcp", "tcp4", "tcp6": 772 raddr, err := inst.ResolveTCPAddr(network, address) 773 if err != nil { 774 return nil, err 775 } 776 return inst.DialTCP(network, nil, raddr) 777 case "udp", "udp4", "udp6": 778 raddr, err := inst.ResolveUDPAddr(network, address) 779 if err != nil { 780 return nil, err 781 } 782 return inst.DialUDP(network, &net.UDPAddr{IP: net.IP{0, 0, 0, 0}}, raddr) 783 default: 784 return nil, fmt.Errorf("unsupported network: %q", network) 785 } 786 } 787 788 // Listen announces on the local network address laddr. The network net must be 789 // a stream-oriented network: "tcp", "tcp4", "tcp6". See Dial for the syntax of 790 // laddr. 791 func (inst Instance) Listen(network, address string) (net.Listener, error) { 792 switch network { 793 case "tcp", "tcp4", "tcp6": 794 addr, err := inst.ResolveTCPAddr(network, address) 795 if err != nil { 796 return nil, err 797 } 798 return inst.ListenTCP(network, addr) 799 default: 800 return nil, fmt.Errorf("unsupported network: %q", network) 801 } 802 }