github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/src/syscall/net_nacl.go (about) 1 // Copyright 2013 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 // A simulated network for use within NaCl. 6 // The simulation is not particularly tied to NaCl, 7 // but other systems have real networks. 8 9 // All int64 times are UnixNanos. 10 11 package syscall 12 13 import ( 14 "sync" 15 "sync/atomic" 16 ) 17 18 // Interface to timers implemented in package runtime. 19 // Must be in sync with ../runtime/runtime.h:/^struct.Timer$ 20 // Really for use by package time, but we cannot import time here. 21 22 type runtimeTimer struct { 23 i int 24 when int64 25 period int64 26 f func(interface{}, uintptr) // NOTE: must not be closure 27 arg interface{} 28 seq uintptr 29 } 30 31 func startTimer(*runtimeTimer) 32 func stopTimer(*runtimeTimer) bool 33 34 type timer struct { 35 expired bool 36 q *queue 37 r runtimeTimer 38 } 39 40 func (t *timer) start(q *queue, deadline int64) { 41 if deadline == 0 { 42 return 43 } 44 t.q = q 45 t.r.when = deadline 46 t.r.f = timerExpired 47 t.r.arg = t 48 startTimer(&t.r) 49 } 50 51 func (t *timer) stop() { 52 stopTimer(&t.r) 53 } 54 55 func (t *timer) reset(q *queue, deadline int64) { 56 if t.r.f != nil { 57 t.stop() 58 } 59 if deadline == 0 { 60 return 61 } 62 if t.r.f == nil { 63 t.q = q 64 t.r.f = timerExpired 65 t.r.arg = t 66 } 67 t.r.when = deadline 68 startTimer(&t.r) 69 } 70 71 func timerExpired(i interface{}, seq uintptr) { 72 t := i.(*timer) 73 go func() { 74 t.q.Lock() 75 defer t.q.Unlock() 76 t.expired = true 77 t.q.canRead.Broadcast() 78 t.q.canWrite.Broadcast() 79 }() 80 } 81 82 // Network constants and data structures. These match the traditional values. 83 84 const ( 85 AF_UNSPEC = iota 86 AF_UNIX 87 AF_INET 88 AF_INET6 89 ) 90 91 const ( 92 SHUT_RD = iota 93 SHUT_WR 94 SHUT_RDWR 95 ) 96 97 const ( 98 SOCK_STREAM = 1 + iota 99 SOCK_DGRAM 100 SOCK_RAW 101 SOCK_SEQPACKET 102 ) 103 104 const ( 105 IPPROTO_IP = 0 106 IPPROTO_IPV4 = 4 107 IPPROTO_IPV6 = 0x29 108 IPPROTO_TCP = 6 109 IPPROTO_UDP = 0x11 110 ) 111 112 // Misc constants expected by package net but not supported. 113 const ( 114 _ = iota 115 SOL_SOCKET 116 SO_TYPE 117 NET_RT_IFLIST 118 IFNAMSIZ 119 IFF_UP 120 IFF_BROADCAST 121 IFF_LOOPBACK 122 IFF_POINTOPOINT 123 IFF_MULTICAST 124 IPV6_V6ONLY 125 SOMAXCONN 126 F_DUPFD_CLOEXEC 127 SO_BROADCAST 128 SO_REUSEADDR 129 SO_REUSEPORT 130 SO_RCVBUF 131 SO_SNDBUF 132 SO_KEEPALIVE 133 SO_LINGER 134 SO_ERROR 135 IP_PORTRANGE 136 IP_PORTRANGE_DEFAULT 137 IP_PORTRANGE_LOW 138 IP_PORTRANGE_HIGH 139 IP_MULTICAST_IF 140 IP_MULTICAST_LOOP 141 IP_ADD_MEMBERSHIP 142 IPV6_PORTRANGE 143 IPV6_PORTRANGE_DEFAULT 144 IPV6_PORTRANGE_LOW 145 IPV6_PORTRANGE_HIGH 146 IPV6_MULTICAST_IF 147 IPV6_MULTICAST_LOOP 148 IPV6_JOIN_GROUP 149 TCP_NODELAY 150 TCP_KEEPINTVL 151 TCP_KEEPIDLE 152 153 SYS_FCNTL = 500 // unsupported 154 ) 155 156 var SocketDisableIPv6 bool 157 158 // A Sockaddr is one of the SockaddrXxx structs. 159 type Sockaddr interface { 160 // copy returns a copy of the underlying data. 161 copy() Sockaddr 162 163 // key returns the value of the underlying data, 164 // for comparison as a map key. 165 key() interface{} 166 } 167 168 type SockaddrInet4 struct { 169 Port int 170 Addr [4]byte 171 } 172 173 func (sa *SockaddrInet4) copy() Sockaddr { 174 sa1 := *sa 175 return &sa1 176 } 177 178 func (sa *SockaddrInet4) key() interface{} { return *sa } 179 180 type SockaddrInet6 struct { 181 Port int 182 ZoneId uint32 183 Addr [16]byte 184 } 185 186 func (sa *SockaddrInet6) copy() Sockaddr { 187 sa1 := *sa 188 return &sa1 189 } 190 191 func (sa *SockaddrInet6) key() interface{} { return *sa } 192 193 type SockaddrUnix struct { 194 Name string 195 } 196 197 func (sa *SockaddrUnix) copy() Sockaddr { 198 sa1 := *sa 199 return &sa1 200 } 201 202 func (sa *SockaddrUnix) key() interface{} { return *sa } 203 204 type SockaddrDatalink struct { 205 Len uint8 206 Family uint8 207 Index uint16 208 Type uint8 209 Nlen uint8 210 Alen uint8 211 Slen uint8 212 Data [12]int8 213 } 214 215 func (sa *SockaddrDatalink) copy() Sockaddr { 216 sa1 := *sa 217 return &sa1 218 } 219 220 func (sa *SockaddrDatalink) key() interface{} { return *sa } 221 222 // RoutingMessage represents a routing message. 223 type RoutingMessage interface { 224 unimplemented() 225 } 226 227 type IPMreq struct { 228 Multiaddr [4]byte /* in_addr */ 229 Interface [4]byte /* in_addr */ 230 } 231 232 type IPv6Mreq struct { 233 Multiaddr [16]byte /* in6_addr */ 234 Interface uint32 235 } 236 237 type Linger struct { 238 Onoff int32 239 Linger int32 240 } 241 242 type ICMPv6Filter struct { 243 Filt [8]uint32 244 } 245 246 // A queue is the bookkeeping for a synchronized buffered queue. 247 // We do not use channels because we need to be able to handle 248 // writes after and during close, and because a chan byte would 249 // require too many send and receive operations in real use. 250 type queue struct { 251 sync.Mutex 252 canRead sync.Cond 253 canWrite sync.Cond 254 rtimer *timer // non-nil if in read 255 wtimer *timer // non-nil if in write 256 r int // total read index 257 w int // total write index 258 m int // index mask 259 closed bool 260 } 261 262 func (q *queue) init(size int) { 263 if size&(size-1) != 0 { 264 panic("invalid queue size - must be power of two") 265 } 266 q.canRead.L = &q.Mutex 267 q.canWrite.L = &q.Mutex 268 q.m = size - 1 269 } 270 271 func past(deadline int64) bool { 272 sec, nsec := now() 273 return deadline > 0 && deadline < sec*1e9+int64(nsec) 274 } 275 276 func (q *queue) waitRead(n int, deadline int64) (int, error) { 277 if past(deadline) { 278 return 0, EAGAIN 279 } 280 var t timer 281 t.start(q, deadline) 282 q.rtimer = &t 283 for q.w-q.r == 0 && !q.closed && !t.expired { 284 q.canRead.Wait() 285 } 286 q.rtimer = nil 287 t.stop() 288 m := q.w - q.r 289 if m == 0 && t.expired { 290 return 0, EAGAIN 291 } 292 if m > n { 293 m = n 294 q.canRead.Signal() // wake up next reader too 295 } 296 q.canWrite.Signal() 297 return m, nil 298 } 299 300 func (q *queue) waitWrite(n int, deadline int64) (int, error) { 301 if past(deadline) { 302 return 0, EAGAIN 303 } 304 var t timer 305 t.start(q, deadline) 306 q.wtimer = &t 307 for q.w-q.r > q.m && !q.closed && !t.expired { 308 q.canWrite.Wait() 309 } 310 q.wtimer = nil 311 t.stop() 312 m := q.m + 1 - (q.w - q.r) 313 if m == 0 && t.expired { 314 return 0, EAGAIN 315 } 316 if m == 0 { 317 return 0, EAGAIN 318 } 319 if m > n { 320 m = n 321 q.canWrite.Signal() // wake up next writer too 322 } 323 q.canRead.Signal() 324 return m, nil 325 } 326 327 func (q *queue) close() { 328 q.Lock() 329 defer q.Unlock() 330 q.closed = true 331 q.canRead.Broadcast() 332 q.canWrite.Broadcast() 333 } 334 335 // A byteq is a byte queue. 336 type byteq struct { 337 queue 338 data []byte 339 } 340 341 func newByteq() *byteq { 342 q := &byteq{ 343 data: make([]byte, 4096), 344 } 345 q.init(len(q.data)) 346 return q 347 } 348 349 func (q *byteq) read(b []byte, deadline int64) (int, error) { 350 q.Lock() 351 defer q.Unlock() 352 n, err := q.waitRead(len(b), deadline) 353 if err != nil { 354 return 0, err 355 } 356 b = b[:n] 357 for len(b) > 0 { 358 m := copy(b, q.data[q.r&q.m:]) 359 q.r += m 360 b = b[m:] 361 } 362 return n, nil 363 } 364 365 func (q *byteq) write(b []byte, deadline int64) (n int, err error) { 366 q.Lock() 367 defer q.Unlock() 368 for n < len(b) { 369 nn, err := q.waitWrite(len(b[n:]), deadline) 370 if err != nil { 371 return n, err 372 } 373 bb := b[n : n+nn] 374 n += nn 375 for len(bb) > 0 { 376 m := copy(q.data[q.w&q.m:], bb) 377 q.w += m 378 bb = bb[m:] 379 } 380 } 381 return n, nil 382 } 383 384 // A msgq is a queue of messages. 385 type msgq struct { 386 queue 387 data []interface{} 388 } 389 390 func newMsgq() *msgq { 391 q := &msgq{ 392 data: make([]interface{}, 32), 393 } 394 q.init(len(q.data)) 395 return q 396 } 397 398 func (q *msgq) read(deadline int64) (interface{}, error) { 399 q.Lock() 400 defer q.Unlock() 401 n, err := q.waitRead(1, deadline) 402 if err != nil { 403 return nil, err 404 } 405 if n == 0 { 406 return nil, nil 407 } 408 m := q.data[q.r&q.m] 409 q.r++ 410 return m, nil 411 } 412 413 func (q *msgq) write(m interface{}, deadline int64) error { 414 q.Lock() 415 defer q.Unlock() 416 _, err := q.waitWrite(1, deadline) 417 if err != nil { 418 return err 419 } 420 q.data[q.w&q.m] = m 421 q.w++ 422 return nil 423 } 424 425 // An addr is a sequence of bytes uniquely identifying a network address. 426 // It is not human-readable. 427 type addr string 428 429 // A conn is one side of a stream-based network connection. 430 // That is, a stream-based network connection is a pair of cross-connected conns. 431 type conn struct { 432 rd *byteq 433 wr *byteq 434 local addr 435 remote addr 436 } 437 438 // A pktconn is one side of a packet-based network connection. 439 // That is, a packet-based network connection is a pair of cross-connected pktconns. 440 type pktconn struct { 441 rd *msgq 442 wr *msgq 443 local addr 444 remote addr 445 } 446 447 // A listener accepts incoming stream-based network connections. 448 type listener struct { 449 rd *msgq 450 local addr 451 } 452 453 // A netFile is an open network file. 454 type netFile struct { 455 defaultFileImpl 456 proto *netproto 457 sotype int 458 listener *msgq 459 packet *msgq 460 rd *byteq 461 wr *byteq 462 rddeadline int64 463 wrdeadline int64 464 addr Sockaddr 465 raddr Sockaddr 466 } 467 468 // A netAddr is a network address in the global listener map. 469 // All the fields must have defined == operations. 470 type netAddr struct { 471 proto *netproto 472 sotype int 473 addr interface{} 474 } 475 476 // net records the state of the network. 477 // It maps a network address to the listener on that address. 478 var net = struct { 479 sync.Mutex 480 listener map[netAddr]*netFile 481 }{ 482 listener: make(map[netAddr]*netFile), 483 } 484 485 // TODO(rsc): Some day, do a better job with port allocation. 486 // For playground programs, incrementing is fine. 487 var nextport = 2 488 489 // A netproto contains protocol-specific functionality 490 // (one for AF_INET, one for AF_INET6 and so on). 491 // It is a struct instead of an interface because the 492 // implementation needs no state, and I expect to 493 // add some data fields at some point. 494 type netproto struct { 495 bind func(*netFile, Sockaddr) error 496 } 497 498 var netprotoAF_INET = &netproto{ 499 bind: func(f *netFile, sa Sockaddr) error { 500 if sa == nil { 501 f.addr = &SockaddrInet4{ 502 Port: nextport, 503 Addr: [4]byte{127, 0, 0, 1}, 504 } 505 nextport++ 506 return nil 507 } 508 addr, ok := sa.(*SockaddrInet4) 509 if !ok { 510 return EINVAL 511 } 512 addr = addr.copy().(*SockaddrInet4) 513 if addr.Port == 0 { 514 addr.Port = nextport 515 nextport++ 516 } 517 f.addr = addr 518 return nil 519 }, 520 } 521 522 var netprotos = map[int]*netproto{ 523 AF_INET: netprotoAF_INET, 524 } 525 526 // These functions implement the usual BSD socket operations. 527 528 func (f *netFile) bind(sa Sockaddr) error { 529 if f.addr != nil { 530 return EISCONN 531 } 532 if err := f.proto.bind(f, sa); err != nil { 533 return err 534 } 535 if f.sotype == SOCK_DGRAM { 536 _, ok := net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] 537 if ok { 538 f.addr = nil 539 return EADDRINUSE 540 } 541 net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] = f 542 f.packet = newMsgq() 543 } 544 return nil 545 } 546 547 func (f *netFile) listen(backlog int) error { 548 net.Lock() 549 defer net.Unlock() 550 if f.listener != nil { 551 return EINVAL 552 } 553 old, ok := net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] 554 if ok && !old.listenerClosed() { 555 return EADDRINUSE 556 } 557 net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] = f 558 f.listener = newMsgq() 559 return nil 560 } 561 562 func (f *netFile) accept() (fd int, sa Sockaddr, err error) { 563 msg, err := f.listener.read(f.readDeadline()) 564 if err != nil { 565 return -1, nil, err 566 } 567 newf, ok := msg.(*netFile) 568 if !ok { 569 // must be eof 570 return -1, nil, EAGAIN 571 } 572 return newFD(newf), newf.raddr.copy(), nil 573 } 574 575 func (f *netFile) connect(sa Sockaddr) error { 576 if past(f.writeDeadline()) { 577 return EAGAIN 578 } 579 if f.addr == nil { 580 if err := f.bind(nil); err != nil { 581 return err 582 } 583 } 584 net.Lock() 585 if sa == nil { 586 net.Unlock() 587 return EINVAL 588 } 589 sa = sa.copy() 590 if f.raddr != nil { 591 net.Unlock() 592 return EISCONN 593 } 594 if f.sotype == SOCK_DGRAM { 595 net.Unlock() 596 f.raddr = sa 597 return nil 598 } 599 if f.listener != nil { 600 net.Unlock() 601 return EISCONN 602 } 603 l, ok := net.listener[netAddr{f.proto, f.sotype, sa.key()}] 604 if !ok || l.listenerClosed() { 605 net.Unlock() 606 return ECONNREFUSED 607 } 608 f.raddr = sa 609 f.rd = newByteq() 610 f.wr = newByteq() 611 newf := &netFile{ 612 proto: f.proto, 613 sotype: f.sotype, 614 addr: f.raddr, 615 raddr: f.addr, 616 rd: f.wr, 617 wr: f.rd, 618 } 619 net.Unlock() 620 l.listener.write(newf, f.writeDeadline()) 621 return nil 622 } 623 624 func (f *netFile) read(b []byte) (int, error) { 625 if f.rd == nil { 626 if f.raddr != nil { 627 n, _, err := f.recvfrom(b, 0) 628 return n, err 629 } 630 return 0, ENOTCONN 631 } 632 return f.rd.read(b, f.readDeadline()) 633 } 634 635 func (f *netFile) write(b []byte) (int, error) { 636 if f.wr == nil { 637 if f.raddr != nil { 638 err := f.sendto(b, 0, f.raddr) 639 var n int 640 if err == nil { 641 n = len(b) 642 } 643 return n, err 644 } 645 return 0, ENOTCONN 646 } 647 return f.wr.write(b, f.writeDeadline()) 648 } 649 650 type pktmsg struct { 651 buf []byte 652 addr Sockaddr 653 } 654 655 func (f *netFile) recvfrom(p []byte, flags int) (n int, from Sockaddr, err error) { 656 if f.sotype != SOCK_DGRAM { 657 return 0, nil, EINVAL 658 } 659 if f.packet == nil { 660 return 0, nil, ENOTCONN 661 } 662 msg1, err := f.packet.read(f.readDeadline()) 663 if err != nil { 664 return 0, nil, err 665 } 666 msg, ok := msg1.(*pktmsg) 667 if !ok { 668 return 0, nil, EAGAIN 669 } 670 return copy(p, msg.buf), msg.addr, nil 671 } 672 673 func (f *netFile) sendto(p []byte, flags int, to Sockaddr) error { 674 if f.sotype != SOCK_DGRAM { 675 return EINVAL 676 } 677 if f.packet == nil { 678 if err := f.bind(nil); err != nil { 679 return err 680 } 681 } 682 net.Lock() 683 if to == nil { 684 net.Unlock() 685 return EINVAL 686 } 687 to = to.copy() 688 l, ok := net.listener[netAddr{f.proto, f.sotype, to.key()}] 689 if !ok || l.packet == nil { 690 net.Unlock() 691 return ECONNREFUSED 692 } 693 net.Unlock() 694 msg := &pktmsg{ 695 buf: make([]byte, len(p)), 696 addr: f.addr, 697 } 698 copy(msg.buf, p) 699 l.packet.write(msg, f.writeDeadline()) 700 return nil 701 } 702 703 func (f *netFile) listenerClosed() bool { 704 f.listener.Lock() 705 defer f.listener.Unlock() 706 return f.listener.closed 707 } 708 709 func (f *netFile) close() error { 710 if f.listener != nil { 711 f.listener.close() 712 } 713 if f.packet != nil { 714 f.packet.close() 715 } 716 if f.rd != nil { 717 f.rd.close() 718 } 719 if f.wr != nil { 720 f.wr.close() 721 } 722 return nil 723 } 724 725 func fdToNetFile(fd int) (*netFile, error) { 726 f, err := fdToFile(fd) 727 if err != nil { 728 return nil, err 729 } 730 impl := f.impl 731 netf, ok := impl.(*netFile) 732 if !ok { 733 return nil, EINVAL 734 } 735 return netf, nil 736 } 737 738 func Socket(proto, sotype, unused int) (fd int, err error) { 739 p := netprotos[proto] 740 if p == nil { 741 return -1, EPROTONOSUPPORT 742 } 743 if sotype != SOCK_STREAM && sotype != SOCK_DGRAM { 744 return -1, ESOCKTNOSUPPORT 745 } 746 f := &netFile{ 747 proto: p, 748 sotype: sotype, 749 } 750 return newFD(f), nil 751 } 752 753 func Bind(fd int, sa Sockaddr) error { 754 f, err := fdToNetFile(fd) 755 if err != nil { 756 return err 757 } 758 return f.bind(sa) 759 } 760 761 func StopIO(fd int) error { 762 f, err := fdToNetFile(fd) 763 if err != nil { 764 return err 765 } 766 f.close() 767 return nil 768 } 769 770 func Listen(fd int, backlog int) error { 771 f, err := fdToNetFile(fd) 772 if err != nil { 773 return err 774 } 775 return f.listen(backlog) 776 } 777 778 func Accept(fd int) (newfd int, sa Sockaddr, err error) { 779 f, err := fdToNetFile(fd) 780 if err != nil { 781 return 0, nil, err 782 } 783 return f.accept() 784 } 785 786 func Getsockname(fd int) (sa Sockaddr, err error) { 787 f, err := fdToNetFile(fd) 788 if err != nil { 789 return nil, err 790 } 791 if f.addr == nil { 792 return nil, ENOTCONN 793 } 794 return f.addr.copy(), nil 795 } 796 797 func Getpeername(fd int) (sa Sockaddr, err error) { 798 f, err := fdToNetFile(fd) 799 if err != nil { 800 return nil, err 801 } 802 if f.raddr == nil { 803 return nil, ENOTCONN 804 } 805 return f.raddr.copy(), nil 806 } 807 808 func Connect(fd int, sa Sockaddr) error { 809 f, err := fdToNetFile(fd) 810 if err != nil { 811 return err 812 } 813 return f.connect(sa) 814 } 815 816 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { 817 f, err := fdToNetFile(fd) 818 if err != nil { 819 return 0, nil, err 820 } 821 return f.recvfrom(p, flags) 822 } 823 824 func Sendto(fd int, p []byte, flags int, to Sockaddr) error { 825 f, err := fdToNetFile(fd) 826 if err != nil { 827 return err 828 } 829 return f.sendto(p, flags, to) 830 } 831 832 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn, recvflags int, from Sockaddr, err error) { 833 f, err := fdToNetFile(fd) 834 if err != nil { 835 return 836 } 837 n, from, err = f.recvfrom(p, flags) 838 return 839 } 840 841 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) error { 842 _, err := SendmsgN(fd, p, oob, to, flags) 843 return err 844 } 845 846 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { 847 f, err := fdToNetFile(fd) 848 if err != nil { 849 return 0, err 850 } 851 switch f.sotype { 852 case SOCK_STREAM: 853 n, err = f.write(p) 854 case SOCK_DGRAM: 855 n = len(p) 856 err = f.sendto(p, flags, to) 857 } 858 if err != nil { 859 return 0, err 860 } 861 return n, nil 862 } 863 864 func GetsockoptInt(fd, level, opt int) (value int, err error) { 865 f, err := fdToNetFile(fd) 866 if err != nil { 867 return 0, err 868 } 869 switch { 870 case level == SOL_SOCKET && opt == SO_TYPE: 871 return f.sotype, nil 872 } 873 return 0, ENOTSUP 874 } 875 876 func SetsockoptInt(fd, level, opt int, value int) error { 877 return nil 878 } 879 880 func SetsockoptByte(fd, level, opt int, value byte) error { 881 _, err := fdToNetFile(fd) 882 if err != nil { 883 return err 884 } 885 return ENOTSUP 886 } 887 888 func SetsockoptLinger(fd, level, opt int, l *Linger) error { 889 return nil 890 } 891 892 func SetReadDeadline(fd int, t int64) error { 893 f, err := fdToNetFile(fd) 894 if err != nil { 895 return err 896 } 897 atomic.StoreInt64(&f.rddeadline, t) 898 if bq := f.rd; bq != nil { 899 bq.Lock() 900 if timer := bq.rtimer; timer != nil { 901 timer.reset(&bq.queue, t) 902 } 903 bq.Unlock() 904 } 905 return nil 906 } 907 908 func (f *netFile) readDeadline() int64 { 909 return atomic.LoadInt64(&f.rddeadline) 910 } 911 912 func SetWriteDeadline(fd int, t int64) error { 913 f, err := fdToNetFile(fd) 914 if err != nil { 915 return err 916 } 917 atomic.StoreInt64(&f.wrdeadline, t) 918 if bq := f.wr; bq != nil { 919 bq.Lock() 920 if timer := bq.wtimer; timer != nil { 921 timer.reset(&bq.queue, t) 922 } 923 bq.Unlock() 924 } 925 return nil 926 } 927 928 func (f *netFile) writeDeadline() int64 { 929 return atomic.LoadInt64(&f.wrdeadline) 930 } 931 932 func Shutdown(fd int, how int) error { 933 f, err := fdToNetFile(fd) 934 if err != nil { 935 return err 936 } 937 switch how { 938 case SHUT_RD: 939 f.rd.close() 940 case SHUT_WR: 941 f.wr.close() 942 case SHUT_RDWR: 943 f.rd.close() 944 f.wr.close() 945 } 946 return nil 947 } 948 949 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error { panic("SetsockoptICMPv") } 950 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) error { panic("SetsockoptIPMreq") } 951 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) error { panic("SetsockoptIPv") } 952 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) error { panic("SetsockoptInet") } 953 func SetsockoptString(fd, level, opt int, s string) error { panic("SetsockoptString") } 954 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) error { panic("SetsockoptTimeval") } 955 func Socketpair(domain, typ, proto int) (fd [2]int, err error) { panic("Socketpair") } 956 957 func SetNonblock(fd int, nonblocking bool) error { return nil }