Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. package flatip
  2. import (
  3. "bytes"
  4. "fmt"
  5. "math/rand"
  6. "net"
  7. "reflect"
  8. "testing"
  9. "time"
  10. )
  11. func easyParseIP(ipstr string) (result net.IP) {
  12. result = net.ParseIP(ipstr)
  13. if result == nil {
  14. panic(ipstr)
  15. }
  16. return
  17. }
  18. func easyParseFlat(ipstr string) (result IP) {
  19. x := easyParseIP(ipstr)
  20. return FromNetIP(x)
  21. }
  22. func easyParseIPNet(nipstr string) (result net.IPNet) {
  23. _, nip, err := net.ParseCIDR(nipstr)
  24. if err != nil {
  25. panic(err)
  26. }
  27. return *nip
  28. }
  29. func TestBasic(t *testing.T) {
  30. nip := easyParseIP("8.8.8.8")
  31. flatip := FromNetIP(nip)
  32. if flatip.String() != "8.8.8.8" {
  33. t.Errorf("conversions don't work")
  34. }
  35. }
  36. func TestLoopback(t *testing.T) {
  37. localhost_v4 := easyParseFlat("127.0.0.1")
  38. localhost_v4_again := easyParseFlat("127.2.3.4")
  39. google := easyParseFlat("8.8.8.8")
  40. loopback_v6 := easyParseFlat("::1")
  41. google_v6 := easyParseFlat("2607:f8b0:4006:801::2004")
  42. if !(localhost_v4.IsLoopback() && localhost_v4_again.IsLoopback() && loopback_v6.IsLoopback()) {
  43. t.Errorf("can't detect loopbacks")
  44. }
  45. if google_v6.IsLoopback() || google.IsLoopback() {
  46. t.Errorf("incorrectly detected loopbacks")
  47. }
  48. }
  49. func TestContains(t *testing.T) {
  50. nipnet := easyParseIPNet("8.8.0.0/16")
  51. flatipnet := FromNetIPNet(nipnet)
  52. nip := easyParseIP("8.8.8.8")
  53. flatip_ := FromNetIP(nip)
  54. if !flatipnet.Contains(flatip_) {
  55. t.Errorf("contains doesn't work")
  56. }
  57. }
  58. var testIPStrs = []string{
  59. "8.8.8.8",
  60. "127.0.0.1",
  61. "1.1.1.1",
  62. "128.127.65.64",
  63. "2001:0db8::1",
  64. "::1",
  65. "255.255.255.255",
  66. }
  67. func doMaskingTest(ip net.IP, t *testing.T) {
  68. flat := FromNetIP(ip)
  69. netLen := len(ip) * 8
  70. for i := 0; i < netLen; i++ {
  71. masked := flat.Mask(i, netLen)
  72. netMask := net.CIDRMask(i, netLen)
  73. netMasked := ip.Mask(netMask)
  74. if !bytes.Equal(masked[:], netMasked.To16()) {
  75. t.Errorf("Masking %s with %d/%d; expected %s, got %s", ip.String(), i, netLen, netMasked.String(), masked.String())
  76. }
  77. }
  78. }
  79. func assertEqual(found, expected interface{}) {
  80. if !reflect.DeepEqual(found, expected) {
  81. panic(fmt.Sprintf("expected %#v, found %#v", expected, found))
  82. }
  83. }
  84. func TestSize(t *testing.T) {
  85. _, net, err := ParseCIDR("8.8.8.8/24")
  86. if err != nil {
  87. panic(err)
  88. }
  89. ones, bits := net.Size()
  90. assertEqual(ones, 24)
  91. assertEqual(bits, 32)
  92. _, net, err = ParseCIDR("2001::0db8/64")
  93. if err != nil {
  94. panic(err)
  95. }
  96. ones, bits = net.Size()
  97. assertEqual(ones, 64)
  98. assertEqual(bits, 128)
  99. _, net, err = ParseCIDR("2001::0db8/96")
  100. if err != nil {
  101. panic(err)
  102. }
  103. ones, bits = net.Size()
  104. assertEqual(ones, 96)
  105. assertEqual(bits, 128)
  106. }
  107. func TestMasking(t *testing.T) {
  108. for _, ipstr := range testIPStrs {
  109. doMaskingTest(easyParseIP(ipstr), t)
  110. }
  111. }
  112. func TestMaskingFuzz(t *testing.T) {
  113. r := rand.New(rand.NewSource(time.Now().UnixNano()))
  114. buf := make([]byte, 4)
  115. for i := 0; i < 10000; i++ {
  116. r.Read(buf)
  117. doMaskingTest(net.IP(buf), t)
  118. }
  119. buf = make([]byte, 16)
  120. for i := 0; i < 10000; i++ {
  121. r.Read(buf)
  122. doMaskingTest(net.IP(buf), t)
  123. }
  124. }
  125. func BenchmarkMasking(b *testing.B) {
  126. ip := easyParseIP("2001:0db8::42")
  127. flat := FromNetIP(ip)
  128. b.ResetTimer()
  129. for i := 0; i < b.N; i++ {
  130. flat.Mask(64, 128)
  131. }
  132. }
  133. func BenchmarkMaskingLegacy(b *testing.B) {
  134. ip := easyParseIP("2001:0db8::42")
  135. mask := net.CIDRMask(64, 128)
  136. b.ResetTimer()
  137. for i := 0; i < b.N; i++ {
  138. ip.Mask(mask)
  139. }
  140. }
  141. func BenchmarkMaskingCached(b *testing.B) {
  142. i := easyParseIP("2001:0db8::42")
  143. flat := FromNetIP(i)
  144. mask := cidrMask(64, 128)
  145. b.ResetTimer()
  146. for i := 0; i < b.N; i++ {
  147. flat.applyMask(mask)
  148. }
  149. }
  150. func BenchmarkMaskingConstruct(b *testing.B) {
  151. for i := 0; i < b.N; i++ {
  152. cidrMask(69, 128)
  153. }
  154. }
  155. func BenchmarkContains(b *testing.B) {
  156. ip := easyParseIP("2001:0db8::42")
  157. flat := FromNetIP(ip)
  158. _, ipnet, err := net.ParseCIDR("2001:0db8::/64")
  159. if err != nil {
  160. panic(err)
  161. }
  162. flatnet := FromNetIPNet(*ipnet)
  163. b.ResetTimer()
  164. for i := 0; i < b.N; i++ {
  165. flatnet.Contains(flat)
  166. }
  167. }
  168. func BenchmarkContainsLegacy(b *testing.B) {
  169. ip := easyParseIP("2001:0db8::42")
  170. _, ipnetptr, err := net.ParseCIDR("2001:0db8::/64")
  171. if err != nil {
  172. panic(err)
  173. }
  174. ipnet := *ipnetptr
  175. b.ResetTimer()
  176. for i := 0; i < b.N; i++ {
  177. ipnet.Contains(ip)
  178. }
  179. }