Advertisement
FlyFar

net.go

Jan 20th, 2024
1,127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 2.93 KB | Cybersecurity | 0 0
  1. package main
  2.  
  3. /*
  4.  * net.go
  5.  * Network functions
  6.  * By J. Stuart McMurray
  7.  * Created 20160226
  8.  * Last Modified 20160226
  9.  */
  10.  
  11. import (
  12.     "fmt"
  13.     "io"
  14.     "log"
  15.     "net"
  16.     "time"
  17. )
  18.  
  19. var HeartBeetError = fmt.Errorf("heartbeet")
  20.  
  21. /* localIP gets a local IP address for the host, or 127.0.0.1 if nothing else
  22. works */
  23. func localIP() (string, error) {
  24.     /* Local addresses */
  25.     addrs, err := net.InterfaceAddrs()
  26.     if nil != err {
  27.         return "127.0.0.1", err
  28.     }
  29.     /* Find the first non-loopback address */
  30.     for _, v := range addrs {
  31.         /* Cast to something we can use */
  32.         i, ok := v.(*net.IPNet)
  33.         if !ok {
  34.             log.Printf("Found strange address: %v", v)
  35.             continue
  36.         }
  37.         /* Only get external addresses */
  38.         if !i.IP.IsGlobalUnicast() {
  39.             continue
  40.         }
  41.         return i.IP.String(), nil
  42.     }
  43.     return "127.0.0.1", nil
  44. }
  45.  
  46. /* resolve resolves addresses to addresses or dies */
  47. func resolve(a string) *net.IPAddr {
  48.     i, err := net.ResolveIPAddr("ip", a)
  49.     if nil != err {
  50.         log.Fatalf("Resolve: %v", err)
  51.     }
  52.     return i
  53. }
  54.  
  55. /* xmit copies bytes from in to out, passing them through crypt in the process.
  56. If there is an error, it will be sent to ec. */
  57. func xmit(
  58.     out io.Writer,
  59.     in io.Reader,
  60.     key [KEYLEN]byte,
  61.     crypt func(buf, msg []byte, key [KEYLEN]byte) ([]byte, error),
  62. ) error {
  63.     var (
  64.         pbuf = make([]byte, BUFLEN) /* Plaintext Buffer */
  65.         cbuf = make([]byte, BUFLEN) /* Ciphertext buffer */
  66.         rerr error                  /* Read error */
  67.         werr error                  /* Write error */
  68.         cerr error                  /* Encryption error */
  69.         n    int                    /* Read length */
  70.     )
  71.     for {
  72.         /* Reset buffer */
  73.         pbuf = pbuf[0:cap(pbuf)]
  74.  
  75.         /* Read a bit */
  76.         n, rerr = in.Read(pbuf)
  77.         /* Trim unused space */
  78.         pbuf = pbuf[:n]
  79.  
  80.         /* If we didn't read anything, try again if there's no error */
  81.         if 0 == n {
  82.             /* If there's an error, give up */
  83.             if nil != rerr {
  84.                 return rerr
  85.             }
  86.             log.Printf("Heartbeet?") /* DEBUG */
  87.         }
  88.  
  89.         /* Crypt and send the message */
  90.         cbuf, cerr = crypt(cbuf, pbuf, key)
  91.         if nil != cerr {
  92.             if HeartBeetError != cerr {
  93.                 log.Printf("Crypt: %v", cerr)
  94.             }
  95.             continue
  96.         }
  97.         _, werr = out.Write(cbuf)
  98.  
  99.         /* If either read or write errored, give up */
  100.         if nil != rerr {
  101.             return rerr
  102.         }
  103.         if nil != werr {
  104.             return werr
  105.         }
  106.     }
  107. }
  108.  
  109. /* heartbeet sends 0-byte messages on c at roughly the given interval, as
  110. keepalives */
  111. func heartbeet(c net.Conn, interval time.Duration) {
  112.     for {
  113.         if _, err := c.Write([]byte{}); nil != err {
  114.             log.Fatalf("Heartbeet: %v", err)
  115.         }
  116.         time.Sleep(interval)
  117.     }
  118. }
  119.  
  120. /* connect "connects" to the other side */
  121. func connect(
  122.     laddr string,
  123.     raddr string,
  124.     proto uint,
  125.     hbint time.Duration,
  126. ) *net.IPConn {
  127.     c, err := net.DialIP(
  128.         fmt.Sprintf("ip:%v", proto),
  129.         resolve(laddr),
  130.         resolve(raddr),
  131.     )
  132.     if nil != err {
  133.         log.Fatalf("Dial: %v", err)
  134.     }
  135.  
  136.     /* Start to heartbeet */
  137.     go heartbeet(c, hbint)
  138.  
  139.     return c
  140. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement