xmpp/layer1.go
changeset 148 b1b4900eee5b
parent 147 d7679d991b17
child 153 bbd4166df95d
equal deleted inserted replaced
147:d7679d991b17 148:b1b4900eee5b
     2 // initial handshake.
     2 // initial handshake.
     3 
     3 
     4 package xmpp
     4 package xmpp
     5 
     5 
     6 import (
     6 import (
       
     7 	"crypto/tls"
     7 	"io"
     8 	"io"
     8 	"net"
     9 	"net"
     9 	"time"
    10 	"time"
    10 )
    11 )
    11 
    12 
    12 func (cl *Client) recvTransport(w io.WriteCloser) {
    13 var l1interval = time.Second
       
    14 
       
    15 type layer1 struct {
       
    16 	sock      net.Conn
       
    17 	recvSocks chan<- net.Conn
       
    18 	sendSocks chan net.Conn
       
    19 }
       
    20 
       
    21 func startLayer1(sock net.Conn, recvWriter io.WriteCloser,
       
    22 	sendReader io.ReadCloser) *layer1 {
       
    23 	l1 := layer1{sock: sock}
       
    24 	recvSocks := make(chan net.Conn)
       
    25 	l1.recvSocks = recvSocks
       
    26 	sendSocks := make(chan net.Conn, 1)
       
    27 	l1.sendSocks = sendSocks
       
    28 	go recvTransport(recvSocks, recvWriter)
       
    29 	go sendTransport(sendSocks, sendReader)
       
    30 	recvSocks <- sock
       
    31 	sendSocks <- sock
       
    32 	return &l1
       
    33 }
       
    34 
       
    35 func (l1 *layer1) startTls(conf *tls.Config) {
       
    36 	sendSockToSender := func(sock net.Conn) {
       
    37 		for {
       
    38 			select {
       
    39 			case <-l1.sendSocks:
       
    40 			case l1.sendSocks <- sock:
       
    41 				return
       
    42 			}
       
    43 		}
       
    44 	}
       
    45 
       
    46 	sendSockToSender(nil)
       
    47 	l1.recvSocks <- nil
       
    48 	l1.sock = tls.Client(l1.sock, conf)
       
    49 	sendSockToSender(l1.sock)
       
    50 	l1.recvSocks <- l1.sock
       
    51 }
       
    52 
       
    53 func recvTransport(socks <-chan net.Conn, w io.WriteCloser) {
    13 	defer w.Close()
    54 	defer w.Close()
       
    55 	var sock net.Conn
    14 	p := make([]byte, 1024)
    56 	p := make([]byte, 1024)
    15 	for {
    57 	for {
    16 		if cl.socket == nil {
    58 		select {
    17 			cl.waitForSocket()
    59 		case sock = <-socks:
       
    60 		default:
    18 		}
    61 		}
    19 		cl.socket.SetReadDeadline(time.Now().Add(time.Second))
    62 
    20 		nr, err := cl.socket.Read(p)
    63 		if sock == nil {
    21 		if nr == 0 {
    64 			time.Sleep(l1interval)
    22 			if errno, ok := err.(*net.OpError); ok {
    65 		} else {
    23 				if errno.Timeout() {
    66 			sock.SetReadDeadline(time.Now().Add(l1interval))
    24 					continue
    67 			nr, err := sock.Read(p)
       
    68 			if nr == 0 {
       
    69 				if errno, ok := err.(*net.OpError); ok {
       
    70 					if errno.Timeout() {
       
    71 						continue
       
    72 					}
    25 				}
    73 				}
       
    74 				Warn.Logf("recvTransport: %s", err)
       
    75 				break
    26 			}
    76 			}
    27 			Warn.Logf("read: %s", err)
    77 			nw, err := w.Write(p[:nr])
    28 			break
    78 			if nw < nr {
    29 		}
    79 				Warn.Logf("recvTransport: %s", err)
    30 		nw, err := w.Write(p[:nr])
    80 				break
    31 		if nw < nr {
    81 			}
    32 			Warn.Logf("read: %s", err)
       
    33 			break
       
    34 		}
    82 		}
    35 	}
    83 	}
    36 }
    84 }
    37 
    85 
    38 func (cl *Client) sendTransport(r io.Reader) {
    86 func sendTransport(socks <-chan net.Conn, r io.Reader) {
    39 	defer cl.socket.Close()
    87 	var sock net.Conn
    40 	p := make([]byte, 1024)
    88 	p := make([]byte, 1024)
    41 	for {
    89 	for {
    42 		nr, err := r.Read(p)
    90 		nr, err := r.Read(p)
    43 		if nr == 0 {
    91 		if nr == 0 {
    44 			Warn.Logf("write: %s", err)
    92 			Warn.Logf("sendTransport: %s", err)
    45 			break
    93 			break
    46 		}
    94 		}
    47 		nw, err := cl.socket.Write(p[:nr])
    95 		for nr > 0 {
    48 		if nw < nr {
    96 			select {
    49 			Warn.Logf("write: %s", err)
    97 			case sock = <-socks:
    50 			break
    98 				if sock != nil {
       
    99 					defer sock.Close()
       
   100 				}
       
   101 			default:
       
   102 			}
       
   103 
       
   104 			if sock == nil {
       
   105 				time.Sleep(l1interval)
       
   106 			} else {
       
   107 				nw, err := sock.Write(p[:nr])
       
   108 				nr -= nw
       
   109 				if nr != 0 {
       
   110 					Warn.Logf("write: %s", err)
       
   111 					break
       
   112 				}
       
   113 			}
    51 		}
   114 		}
    52 	}
   115 	}
    53 }
   116 }