network.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package client
  2. import (
  3. "bytes"
  4. "fmt"
  5. "math/rand"
  6. "net"
  7. "time"
  8. )
  9. func (cl *Client) SendToKDC(b []byte) ([]byte, error) {
  10. var rb []byte
  11. var kdcs []string
  12. for _, r := range cl.Config.Realms {
  13. if r.Realm == cl.Config.LibDefaults.Default_realm {
  14. kdcs = r.Kdc
  15. break
  16. }
  17. }
  18. if len(kdcs) < 1 {
  19. return rb, fmt.Errorf("No KDCs defined in configuration for realm %v", cl.Config.LibDefaults.Default_realm)
  20. }
  21. var kdc string
  22. if len(kdcs) > 1 {
  23. //Select one of the KDCs at random
  24. kdc = kdcs[rand.Intn(len(kdcs))]
  25. } else {
  26. kdc = kdcs[0]
  27. }
  28. if cl.Config.LibDefaults.Udp_preference_limit == 1 {
  29. //1 means we should always use TCP
  30. rb, errtcp := sendTCP(kdc, b)
  31. if errtcp != nil {
  32. return rb, fmt.Errorf("Failed to communicate with KDC %v via TDP (%v)", kdc, errtcp)
  33. }
  34. if len(rb) < 1 {
  35. return rb, fmt.Errorf("No response data from KDC %v", kdc)
  36. }
  37. return rb, nil
  38. }
  39. if len(b) <= cl.Config.LibDefaults.Udp_preference_limit {
  40. //Try UDP first, TCP second
  41. rb, errudp := sendUDP(kdc, b)
  42. if errudp != nil {
  43. rb, errtcp := sendTCP(kdc, b)
  44. if errtcp != nil {
  45. return rb, fmt.Errorf("Failed to communicate with KDC %v via UDP (%v) and then via TDP (%v)", kdc, errudp, errtcp)
  46. }
  47. }
  48. if len(rb) < 1 {
  49. return rb, fmt.Errorf("No response data from KDC %v", kdc)
  50. }
  51. return rb, nil
  52. }
  53. //Try TCP first, UDP second
  54. rb, errtcp := sendTCP(kdc, b)
  55. if errtcp != nil {
  56. rb, errudp := sendUDP(kdc, b)
  57. if errudp != nil {
  58. return rb, fmt.Errorf("Failed to communicate with KDC %v via TCP (%v) and then via UDP (%v)", kdc, errtcp, errudp)
  59. }
  60. }
  61. if len(rb) < 1 {
  62. return rb, fmt.Errorf("No response data from KDC %v", kdc)
  63. }
  64. return rb, nil
  65. }
  66. func sendUDP(kdc string, b []byte) ([]byte, error) {
  67. var r []byte
  68. udpAddr, err := net.ResolveUDPAddr("udp", kdc)
  69. if err != nil {
  70. return r, fmt.Errorf("Error resolving KDC address: %v", err)
  71. }
  72. conn, err := net.DialUDP("udp", nil, udpAddr)
  73. if err != nil {
  74. return r, fmt.Errorf("Error establishing connection to KDC: %v", err)
  75. }
  76. defer conn.Close()
  77. conn.SetDeadline(time.Now().Add(time.Duration(5 * time.Second)))
  78. _, err = conn.Write(b)
  79. if err != nil {
  80. return r, fmt.Errorf("Error sending to KDC: %v", err)
  81. }
  82. udpbuf := make([]byte, 4096)
  83. n, _, err := conn.ReadFrom(udpbuf)
  84. r = udpbuf[:n]
  85. if err != nil {
  86. return r, fmt.Errorf("Sending over UDP failed: %v", err)
  87. }
  88. return r, nil
  89. }
  90. func sendTCP(kdc string, b []byte) ([]byte, error) {
  91. var r []byte
  92. tcpAddr, err := net.ResolveTCPAddr("tcp", kdc)
  93. if err != nil {
  94. return r, fmt.Errorf("Error resolving KDC address: %v", err)
  95. }
  96. conn, err := net.DialTCP("tcp", nil, tcpAddr)
  97. if err != nil {
  98. return r, fmt.Errorf("Error establishing connection to KDC: %v", err)
  99. }
  100. defer conn.Close()
  101. conn.SetDeadline(time.Now().Add(time.Duration(5 * time.Second)))
  102. _, err = conn.Write(b)
  103. if err != nil {
  104. return r, fmt.Errorf("Error sending to KDC: %v", err)
  105. }
  106. tcpbuf := bytes.NewBuffer(make([]byte, 4096))
  107. n, err := conn.ReadFrom(tcpbuf)
  108. r = tcpbuf.Bytes()[:n]
  109. if err != nil {
  110. return r, fmt.Errorf("Sending over TCP failed: %v", err)
  111. }
  112. return r, nil
  113. }