xmpp/layer1.go
changeset 163 3f891f7fe817
parent 153 bbd4166df95d
child 167 7ce61108ed86
equal deleted inserted replaced
162:7b5586a5e109 163:3f891f7fe817
     3 
     3 
     4 package xmpp
     4 package xmpp
     5 
     5 
     6 import (
     6 import (
     7 	"crypto/tls"
     7 	"crypto/tls"
       
     8 	"fmt"
     8 	"io"
     9 	"io"
       
    10 	"log"
     9 	"net"
    11 	"net"
    10 	"time"
    12 	"time"
    11 )
    13 )
       
    14 
       
    15 // If enabled, print all sent and received XML.
       
    16 var Debug = false
    12 
    17 
    13 var l1interval = time.Second
    18 var l1interval = time.Second
    14 
    19 
    15 type layer1 struct {
    20 type layer1 struct {
    16 	sock      net.Conn
    21 	sock      net.Conn
    17 	recvSocks chan<- net.Conn
    22 	recvSocks chan<- net.Conn
    18 	sendSocks chan net.Conn
    23 	sendSocks chan net.Conn
    19 }
    24 }
    20 
    25 
    21 func startLayer1(sock net.Conn, recvWriter io.WriteCloser,
    26 func (cl *Client) startLayer1(sock net.Conn, recvWriter io.WriteCloser,
    22 	sendReader io.ReadCloser, status <-chan Status) *layer1 {
    27 	sendReader io.ReadCloser, status <-chan Status) *layer1 {
    23 	l1 := layer1{sock: sock}
    28 	l1 := layer1{sock: sock}
    24 	recvSocks := make(chan net.Conn)
    29 	recvSocks := make(chan net.Conn)
    25 	l1.recvSocks = recvSocks
    30 	l1.recvSocks = recvSocks
    26 	sendSocks := make(chan net.Conn, 1)
    31 	sendSocks := make(chan net.Conn, 1)
    27 	l1.sendSocks = sendSocks
    32 	l1.sendSocks = sendSocks
    28 	go recvTransport(recvSocks, recvWriter, status)
    33 	go cl.recvTransport(recvSocks, recvWriter, status)
    29 	go sendTransport(sendSocks, sendReader)
    34 	go cl.sendTransport(sendSocks, sendReader)
    30 	recvSocks <- sock
    35 	recvSocks <- sock
    31 	sendSocks <- sock
    36 	sendSocks <- sock
    32 	return &l1
    37 	return &l1
    33 }
    38 }
    34 
    39 
    48 	l1.sock = tls.Client(l1.sock, conf)
    53 	l1.sock = tls.Client(l1.sock, conf)
    49 	sendSockToSender(l1.sock)
    54 	sendSockToSender(l1.sock)
    50 	l1.recvSocks <- l1.sock
    55 	l1.recvSocks <- l1.sock
    51 }
    56 }
    52 
    57 
    53 func recvTransport(socks <-chan net.Conn, w io.WriteCloser,
    58 func (cl *Client) recvTransport(socks <-chan net.Conn, w io.WriteCloser,
    54 	status <-chan Status) {
    59 	status <-chan Status) {
    55 
    60 
    56 	defer w.Close()
    61 	defer w.Close()
    57 	var sock net.Conn
    62 	var sock net.Conn
    58 	p := make([]byte, 1024)
    63 	p := make([]byte, 1024)
    59 	for {
    64 	for {
    60 		select {
    65 		select {
    61 		case stat := <-status:
    66 		case stat := <-status:
    62 			if stat == StatusShutdown {
    67 			if stat.fatal() {
    63 				return
    68 				return
    64 			}
    69 			}
    65 
    70 
    66 		case sock = <-socks:
    71 		case sock = <-socks:
    67 		default:
    72 		default:
    76 				if errno, ok := err.(*net.OpError); ok {
    81 				if errno, ok := err.(*net.OpError); ok {
    77 					if errno.Timeout() {
    82 					if errno.Timeout() {
    78 						continue
    83 						continue
    79 					}
    84 					}
    80 				}
    85 				}
    81 				Warn.Logf("recvTransport: %s", err)
    86 				cl.setError(fmt.Errorf("recv: %v", err))
    82 				return
    87 				return
       
    88 			}
       
    89 			if Debug {
       
    90 				log.Printf("recv: %s", p[:nr])
    83 			}
    91 			}
    84 			nw, err := w.Write(p[:nr])
    92 			nw, err := w.Write(p[:nr])
    85 			if nw < nr {
    93 			if nw < nr {
    86 				Warn.Logf("recvTransport: %s", err)
    94 				cl.setError(fmt.Errorf("recv: %v", err))
    87 				return
    95 				return
    88 			}
    96 			}
    89 		}
    97 		}
    90 	}
    98 	}
    91 }
    99 }
    92 
   100 
    93 func sendTransport(socks <-chan net.Conn, r io.Reader) {
   101 func (cl *Client) sendTransport(socks <-chan net.Conn, r io.Reader) {
    94 	var sock net.Conn
   102 	var sock net.Conn
    95 	p := make([]byte, 1024)
   103 	p := make([]byte, 1024)
    96 	for {
   104 	for {
    97 		nr, err := r.Read(p)
   105 		nr, err := r.Read(p)
    98 		if nr == 0 {
   106 		if nr == 0 {
    99 			Warn.Logf("sendTransport: %s", err)
   107 			cl.setError(fmt.Errorf("send: %v", err))
   100 			break
   108 			break
       
   109 		}
       
   110 		if nr > 0 && Debug {
       
   111 			log.Printf("send: %s", p[:nr])
   101 		}
   112 		}
   102 		for nr > 0 {
   113 		for nr > 0 {
   103 			select {
   114 			select {
   104 			case sock = <-socks:
   115 			case sock = <-socks:
   105 				if sock != nil {
   116 				if sock != nil {
   112 				time.Sleep(l1interval)
   123 				time.Sleep(l1interval)
   113 			} else {
   124 			} else {
   114 				nw, err := sock.Write(p[:nr])
   125 				nw, err := sock.Write(p[:nr])
   115 				nr -= nw
   126 				nr -= nw
   116 				if nr != 0 {
   127 				if nr != 0 {
   117 					Warn.Logf("write: %s", err)
   128 					cl.setError(fmt.Errorf("send: %v", err))
   118 					break
   129 					break
   119 				}
   130 				}
   120 			}
   131 			}
   121 		}
   132 		}
   122 	}
   133 	}