Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- /*
- * net.go
- * Network functions
- * By J. Stuart McMurray
- * Created 20160226
- * Last Modified 20160226
- */
- import (
- "fmt"
- "io"
- "log"
- "net"
- "time"
- )
- var HeartBeetError = fmt.Errorf("heartbeet")
- /* localIP gets a local IP address for the host, or 127.0.0.1 if nothing else
- works */
- func localIP() (string, error) {
- /* Local addresses */
- addrs, err := net.InterfaceAddrs()
- if nil != err {
- return "127.0.0.1", err
- }
- /* Find the first non-loopback address */
- for _, v := range addrs {
- /* Cast to something we can use */
- i, ok := v.(*net.IPNet)
- if !ok {
- log.Printf("Found strange address: %v", v)
- continue
- }
- /* Only get external addresses */
- if !i.IP.IsGlobalUnicast() {
- continue
- }
- return i.IP.String(), nil
- }
- return "127.0.0.1", nil
- }
- /* resolve resolves addresses to addresses or dies */
- func resolve(a string) *net.IPAddr {
- i, err := net.ResolveIPAddr("ip", a)
- if nil != err {
- log.Fatalf("Resolve: %v", err)
- }
- return i
- }
- /* xmit copies bytes from in to out, passing them through crypt in the process.
- If there is an error, it will be sent to ec. */
- func xmit(
- out io.Writer,
- in io.Reader,
- key [KEYLEN]byte,
- crypt func(buf, msg []byte, key [KEYLEN]byte) ([]byte, error),
- ) error {
- var (
- pbuf = make([]byte, BUFLEN) /* Plaintext Buffer */
- cbuf = make([]byte, BUFLEN) /* Ciphertext buffer */
- rerr error /* Read error */
- werr error /* Write error */
- cerr error /* Encryption error */
- n int /* Read length */
- )
- for {
- /* Reset buffer */
- pbuf = pbuf[0:cap(pbuf)]
- /* Read a bit */
- n, rerr = in.Read(pbuf)
- /* Trim unused space */
- pbuf = pbuf[:n]
- /* If we didn't read anything, try again if there's no error */
- if 0 == n {
- /* If there's an error, give up */
- if nil != rerr {
- return rerr
- }
- log.Printf("Heartbeet?") /* DEBUG */
- }
- /* Crypt and send the message */
- cbuf, cerr = crypt(cbuf, pbuf, key)
- if nil != cerr {
- if HeartBeetError != cerr {
- log.Printf("Crypt: %v", cerr)
- }
- continue
- }
- _, werr = out.Write(cbuf)
- /* If either read or write errored, give up */
- if nil != rerr {
- return rerr
- }
- if nil != werr {
- return werr
- }
- }
- }
- /* heartbeet sends 0-byte messages on c at roughly the given interval, as
- keepalives */
- func heartbeet(c net.Conn, interval time.Duration) {
- for {
- if _, err := c.Write([]byte{}); nil != err {
- log.Fatalf("Heartbeet: %v", err)
- }
- time.Sleep(interval)
- }
- }
- /* connect "connects" to the other side */
- func connect(
- laddr string,
- raddr string,
- proto uint,
- hbint time.Duration,
- ) *net.IPConn {
- c, err := net.DialIP(
- fmt.Sprintf("ip:%v", proto),
- resolve(laddr),
- resolve(raddr),
- )
- if nil != err {
- log.Fatalf("Dial: %v", err)
- }
- /* Start to heartbeet */
- go heartbeet(c, hbint)
- return c
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement