unicastsockopt_test.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright 2012 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. // +build darwin freebsd linux netbsd openbsd windows
  5. package ipv4_test
  6. import (
  7. "code.google.com/p/go.net/ipv4"
  8. "errors"
  9. "net"
  10. "os"
  11. "runtime"
  12. "testing"
  13. )
  14. type testUnicastConn interface {
  15. TOS() (int, error)
  16. SetTOS(int) error
  17. TTL() (int, error)
  18. SetTTL(int) error
  19. }
  20. type unicastSockoptTest struct {
  21. tos int
  22. ttl int
  23. }
  24. var unicastSockoptTests = []unicastSockoptTest{
  25. {DiffServCS0 | NotECNTransport, 127},
  26. {DiffServAF11 | NotECNTransport, 255},
  27. }
  28. func TestTCPUnicastSockopt(t *testing.T) {
  29. for _, tt := range unicastSockoptTests {
  30. listener := make(chan net.Listener)
  31. go tcpListener(t, "127.0.0.1:0", listener)
  32. ln := <-listener
  33. if ln == nil {
  34. return
  35. }
  36. defer ln.Close()
  37. c, err := net.Dial("tcp4", ln.Addr().String())
  38. if err != nil {
  39. t.Errorf("net.Dial failed: %v", err)
  40. return
  41. }
  42. defer c.Close()
  43. cc := ipv4.NewConn(c)
  44. if err := testUnicastSockopt(t, tt, cc); err != nil {
  45. break
  46. }
  47. }
  48. }
  49. func tcpListener(t *testing.T, addr string, listener chan<- net.Listener) {
  50. ln, err := net.Listen("tcp4", addr)
  51. if err != nil {
  52. t.Errorf("net.Listen failed: %v", err)
  53. listener <- nil
  54. return
  55. }
  56. listener <- ln
  57. c, err := ln.Accept()
  58. if err != nil {
  59. return
  60. }
  61. c.Close()
  62. }
  63. func TestUDPUnicastSockopt(t *testing.T) {
  64. for _, tt := range unicastSockoptTests {
  65. c, err := net.ListenPacket("udp4", "127.0.0.1:0")
  66. if err != nil {
  67. t.Errorf("net.ListenPacket failed: %v", err)
  68. return
  69. }
  70. defer c.Close()
  71. p := ipv4.NewPacketConn(c)
  72. if err := testUnicastSockopt(t, tt, p); err != nil {
  73. break
  74. }
  75. }
  76. }
  77. func TestIPUnicastSockopt(t *testing.T) {
  78. if os.Getuid() != 0 {
  79. t.Skip("must be root")
  80. }
  81. for _, tt := range unicastSockoptTests {
  82. c, err := net.ListenPacket("ip4:icmp", "127.0.0.1")
  83. if err != nil {
  84. t.Errorf("net.ListenPacket failed: %v", err)
  85. return
  86. }
  87. defer c.Close()
  88. r, err := ipv4.NewRawConn(c)
  89. if err != nil {
  90. t.Errorf("ipv4.NewRawConn failed: %v", err)
  91. return
  92. }
  93. if err := testUnicastSockopt(t, tt, r); err != nil {
  94. break
  95. }
  96. }
  97. }
  98. func testUnicastSockopt(t *testing.T, tt unicastSockoptTest, c testUnicastConn) error {
  99. switch runtime.GOOS {
  100. case "windows":
  101. // IP_TOS option is supported on Windows 8 and beyond.
  102. t.Logf("skipping IP_TOS test on %q", runtime.GOOS)
  103. default:
  104. if err := c.SetTOS(tt.tos); err != nil {
  105. t.Errorf("ipv4.Conn.SetTOS failed: %v", err)
  106. return err
  107. }
  108. if v, err := c.TOS(); err != nil {
  109. t.Errorf("ipv4.Conn.TOS failed: %v", err)
  110. return err
  111. } else if v != tt.tos {
  112. t.Errorf("Got unexpected TOS value %v; expected %v", v, tt.tos)
  113. return errors.New("Got unexpected TOS value")
  114. }
  115. }
  116. if err := c.SetTTL(tt.ttl); err != nil {
  117. t.Errorf("ipv4.Conn.SetTTL failed: %v", err)
  118. return err
  119. }
  120. if v, err := c.TTL(); err != nil {
  121. t.Errorf("ipv4.Conn.TTL failed: %v", err)
  122. return err
  123. } else if v != tt.ttl {
  124. t.Errorf("Got unexpected TTL value %v; expected %v", v, tt.ttl)
  125. return errors.New("Got unexpected TTL value")
  126. }
  127. return nil
  128. }