host.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. package host
  2. import (
  3. "fmt"
  4. "net"
  5. "os"
  6. "strconv"
  7. "strings"
  8. "git.giaever.org/joachimmg/go-log.git/log"
  9. "git.giaever.org/joachimmg/m-dns/errors"
  10. )
  11. type HostString string
  12. type HostIP net.IP
  13. type HostIPs []HostIP
  14. type HostIPvType int
  15. type HostPort int
  16. const (
  17. IPv4 HostIPvType = iota << 1
  18. IPv6 HostIPvType = iota << 1
  19. NoIP HostIPvType = iota << 1
  20. )
  21. type Host struct {
  22. service HostString
  23. domain HostString
  24. hostname HostString
  25. ips HostIPs
  26. port HostPort
  27. }
  28. func New() *Host {
  29. return new(Host)
  30. }
  31. func (h *Host) SetService(s string) error {
  32. if err := HostString(s).validService(); err != nil {
  33. return err
  34. }
  35. h.service = HostString(s)
  36. return nil
  37. }
  38. func (h *Host) SetDomain(d string) error {
  39. if len(d) == 0 {
  40. d = "local."
  41. }
  42. if err := HostString(d).validDomain(); err != nil {
  43. return err
  44. }
  45. h.domain = HostString(d)
  46. return nil
  47. }
  48. func (h *Host) SetHostname(hn string) error {
  49. if len(hn) == 0 {
  50. var err error
  51. hn, err = os.Hostname()
  52. if err != nil {
  53. log.Warningln(h, hn, err)
  54. return errors.HostHostnameCouldNotDetermine
  55. }
  56. hn = fmt.Sprintf("%s.", hn)
  57. }
  58. if err := HostString(hn).validHostname(); err != nil {
  59. return err
  60. }
  61. h.hostname = HostString(hn)
  62. return nil
  63. }
  64. func (h *Host) SetIPs(i []net.IP) error {
  65. if len(i) == 0 {
  66. var err error
  67. i, err = net.LookupIP(fmt.Sprintf("%s%s", h.GetHostname(), h.GetDomain()))
  68. if err != nil {
  69. log.Warningln(h, err)
  70. return errors.HostIPCouldNotDetermine
  71. }
  72. }
  73. var ips HostIPs
  74. for _, ip := range i {
  75. ips = append(ips, HostIP(ip))
  76. }
  77. if err := ips.validIPs(); err != nil {
  78. log.Warningln(err)
  79. return err
  80. }
  81. h.ips = ips
  82. return nil
  83. }
  84. func (h *Host) SetPort(p int) error {
  85. if err := HostPort(p).validPort(); err != nil {
  86. return err
  87. }
  88. h.port = HostPort(p)
  89. return nil
  90. }
  91. func (h *Host) GetService() HostString {
  92. if err := h.service.validService(); err != nil {
  93. log.Panicln(err)
  94. }
  95. return h.service
  96. }
  97. func (h *Host) GetDomain() HostString {
  98. if err := h.domain.validDomain(); err != nil {
  99. log.Panicln(err)
  100. }
  101. return h.domain
  102. }
  103. func (h *Host) GetHostname() HostString {
  104. if err := h.hostname.validHostname(); err != nil {
  105. log.Panicln(err)
  106. }
  107. return h.hostname
  108. }
  109. func (h *Host) GetIPs() HostIPs {
  110. if err := h.ips.validIPs(); err != nil {
  111. log.Panicln(err)
  112. }
  113. return h.ips
  114. }
  115. func (h *Host) GetPort() HostPort {
  116. if err := h.port.validPort(); err != nil {
  117. log.Panicln(err)
  118. }
  119. return h.port
  120. }
  121. func (h *Host) String() string {
  122. return fmt.Sprintf("Service: %s\nDomain: %s\nHostname: %s\nIPs: %s\nPort: %s\n",
  123. h.GetService(),
  124. h.GetDomain(),
  125. h.GetHostname(),
  126. strings.Join(h.GetIPs().String(), ", "),
  127. h.GetPort(),
  128. )
  129. }
  130. func (h HostString) ValidFQDM() bool {
  131. if len(h) == 0 {
  132. log.Warningln("Cannot be blank", h)
  133. return false
  134. }
  135. if h[len(h)-1] != '.' {
  136. log.Warningf("Missing trailing '.' in <%s>", h)
  137. return false
  138. }
  139. return true
  140. }
  141. func (h HostString) validService() error {
  142. if len(h) == 0 {
  143. log.Warningln("Service is empty", h)
  144. return errors.HostServiceIsEmpty
  145. }
  146. return nil
  147. }
  148. func (h HostString) validHostname() error {
  149. if !h.ValidFQDM() {
  150. return errors.HostHostnameNotFQDM
  151. }
  152. return nil
  153. }
  154. func (h HostString) validDomain() error {
  155. if !h.ValidFQDM() {
  156. return errors.HostDomainNotFQDM
  157. }
  158. return nil
  159. }
  160. func (h HostString) TrimDot() string {
  161. return strings.Trim(h.String(), ".")
  162. }
  163. func (h HostString) String() string {
  164. return string(h)
  165. }
  166. func (h HostIPs) validIPs() error {
  167. for _, ip := range h {
  168. if t := ip.Type(); t == NoIP {
  169. return errors.HostIPAddressIsInvalid
  170. }
  171. }
  172. return nil
  173. }
  174. func (h HostIPs) String() []string {
  175. s := []string{}
  176. for _, ip := range h {
  177. s = append(s, ip.String())
  178. }
  179. return s
  180. }
  181. func (h HostIP) Type() HostIPvType {
  182. if h.AsIP().To4() != nil {
  183. return IPv4
  184. }
  185. if h.AsIP().To16() != nil {
  186. return IPv6
  187. }
  188. return NoIP
  189. }
  190. func (h HostIP) AsIP() net.IP {
  191. return net.IP(h)
  192. }
  193. func (h HostIP) String() string {
  194. return h.AsIP().String()
  195. }
  196. func (h HostPort) validPort() error {
  197. if h <= 0 {
  198. log.Warningf("Port <%d> is invalid.", h)
  199. return errors.HostPortInvalid
  200. }
  201. return nil
  202. }
  203. func (h HostPort) Uint16() uint16 {
  204. return uint16(h)
  205. }
  206. func (h HostPort) String() string {
  207. return strconv.Itoa(int(h))
  208. }