helpers.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Forked from github.com/StefanKopieczek/gossip by @StefanKopieczek
  2. package util
  3. import (
  4. "errors"
  5. "net"
  6. "sync"
  7. )
  8. // Check two string pointers for equality as follows:
  9. // - If neither pointer is nil, check equality of the underlying strings.
  10. // - If either pointer is nil, return true if and only if they both are.
  11. func StrPtrEq(a *string, b *string) bool {
  12. if a == nil || b == nil {
  13. return a == b
  14. }
  15. return *a == *b
  16. }
  17. // Check two uint16 pointers for equality as follows:
  18. // - If neither pointer is nil, check equality of the underlying uint16s.
  19. // - If either pointer is nil, return true if and only if they both are.
  20. func Uint16PtrEq(a *uint16, b *uint16) bool {
  21. if a == nil || b == nil {
  22. return a == b
  23. }
  24. return *a == *b
  25. }
  26. func Coalesce(arg1 interface{}, arg2 interface{}, args ...interface{}) interface{} {
  27. all := append([]interface{}{arg1, arg2}, args...)
  28. for _, arg := range all {
  29. if arg != nil {
  30. return arg
  31. }
  32. }
  33. return nil
  34. }
  35. func Noop() {}
  36. func MergeErrs(chs ...<-chan error) <-chan error {
  37. wg := new(sync.WaitGroup)
  38. out := make(chan error)
  39. pipe := func(ch <-chan error) {
  40. defer wg.Done()
  41. for err := range ch {
  42. out <- err
  43. }
  44. }
  45. wg.Add(len(chs))
  46. for _, ch := range chs {
  47. go pipe(ch)
  48. }
  49. go func() {
  50. wg.Wait()
  51. close(out)
  52. }()
  53. return out
  54. }
  55. func ResolveSelfIP() (net.IP, error) {
  56. ifaces, err := net.Interfaces()
  57. if err != nil {
  58. return nil, err
  59. }
  60. for _, iface := range ifaces {
  61. if iface.Flags&net.FlagUp == 0 {
  62. continue // interface down
  63. }
  64. if iface.Flags&net.FlagLoopback != 0 {
  65. continue // loopback interface
  66. }
  67. addrs, err := iface.Addrs()
  68. if err != nil {
  69. return nil, err
  70. }
  71. for _, addr := range addrs {
  72. var ip net.IP
  73. switch v := addr.(type) {
  74. case *net.IPNet:
  75. ip = v.IP
  76. case *net.IPAddr:
  77. ip = v.IP
  78. }
  79. if ip == nil || ip.IsLoopback() {
  80. continue
  81. }
  82. ip = ip.To4()
  83. if ip == nil {
  84. continue // not an ipv4 address
  85. }
  86. return ip, nil
  87. }
  88. }
  89. return nil, errors.New("server not connected to any network")
  90. }