network.go 3.1 KB

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