parent
ebe78b393d
commit
9c63ad9791
19
Makefile
Normal file
19
Makefile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
# Use of this source code is governed by a BSD-style
|
||||||
|
# license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
include $(GOROOT)/src/Make.$(GOARCH)
|
||||||
|
|
||||||
|
TARG=crypto/tls
|
||||||
|
GOFILES=\
|
||||||
|
alert.go\
|
||||||
|
common.go\
|
||||||
|
handshake_messages.go\
|
||||||
|
handshake_server.go\
|
||||||
|
prf.go\
|
||||||
|
record_process.go\
|
||||||
|
record_read.go\
|
||||||
|
record_write.go\
|
||||||
|
tls.go\
|
||||||
|
|
||||||
|
include $(GOROOT)/src/Make.pkg
|
172
tls.go
Normal file
172
tls.go
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// This package partially implements the TLS 1.1 protocol, as specified in RFC 4346.
|
||||||
|
package tls
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes";
|
||||||
|
"io";
|
||||||
|
"os";
|
||||||
|
"net";
|
||||||
|
"time";
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Conn represents a secure connection.
|
||||||
|
type Conn struct {
|
||||||
|
net.Conn;
|
||||||
|
writeChan chan<- []byte;
|
||||||
|
readChan <-chan []byte;
|
||||||
|
requestChan chan<- interface{};
|
||||||
|
readBuf []byte;
|
||||||
|
eof bool;
|
||||||
|
readTimeout, writeTimeout int64;
|
||||||
|
}
|
||||||
|
|
||||||
|
func timeout(c chan<- bool, nsecs int64) {
|
||||||
|
time.Sleep(nsecs);
|
||||||
|
c <- true;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tls *Conn) Read(p []byte) (int, os.Error) {
|
||||||
|
if len(tls.readBuf) == 0 {
|
||||||
|
if tls.eof {
|
||||||
|
return 0, os.EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
var timeoutChan chan bool;
|
||||||
|
if tls.readTimeout > 0 {
|
||||||
|
timeoutChan = make(chan bool);
|
||||||
|
go timeout(timeoutChan, tls.readTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case b := <-tls.readChan:
|
||||||
|
tls.readBuf = b;
|
||||||
|
case <-timeoutChan:
|
||||||
|
return 0, os.EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TLS distinguishes between orderly closes and truncations. An
|
||||||
|
// orderly close is represented by a zero length slice.
|
||||||
|
if closed(tls.readChan) {
|
||||||
|
return 0, io.ErrUnexpectedEOF;
|
||||||
|
}
|
||||||
|
if len(tls.readBuf) == 0 {
|
||||||
|
tls.eof = true;
|
||||||
|
return 0, os.EOF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n := bytes.Copy(p, tls.readBuf);
|
||||||
|
tls.readBuf = tls.readBuf[n:len(tls.readBuf)];
|
||||||
|
return n, nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tls *Conn) Write(p []byte) (int, os.Error) {
|
||||||
|
if tls.eof || closed(tls.readChan) {
|
||||||
|
return 0, os.EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
var timeoutChan chan bool;
|
||||||
|
if tls.writeTimeout > 0 {
|
||||||
|
timeoutChan = make(chan bool);
|
||||||
|
go timeout(timeoutChan, tls.writeTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case tls.writeChan <- p:
|
||||||
|
case <-timeoutChan:
|
||||||
|
return 0, os.EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len(p), nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tls *Conn) Close() os.Error {
|
||||||
|
close(tls.writeChan);
|
||||||
|
close(tls.requestChan);
|
||||||
|
tls.eof = true;
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tls *Conn) SetTimeout(nsec int64) os.Error {
|
||||||
|
tls.readTimeout = nsec;
|
||||||
|
tls.writeTimeout = nsec;
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tls *Conn) SetReadTimeout(nsec int64) os.Error {
|
||||||
|
tls.readTimeout = nsec;
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tls *Conn) SetWriteTimeout(nsec int64) os.Error {
|
||||||
|
tls.writeTimeout = nsec;
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tls *Conn) GetConnectionState() ConnectionState {
|
||||||
|
replyChan := make(chan ConnectionState);
|
||||||
|
tls.requestChan <- getConnectionState{replyChan};
|
||||||
|
return <-replyChan;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Server establishes a secure connection over the given connection and acts
|
||||||
|
// as a TLS server.
|
||||||
|
func Server(conn net.Conn, config *Config) *Conn {
|
||||||
|
tls := new(Conn);
|
||||||
|
tls.Conn = conn;
|
||||||
|
|
||||||
|
writeChan := make(chan []byte);
|
||||||
|
readChan := make(chan []byte);
|
||||||
|
requestChan := make(chan interface{});
|
||||||
|
|
||||||
|
tls.writeChan = writeChan;
|
||||||
|
tls.readChan = readChan;
|
||||||
|
tls.requestChan = requestChan;
|
||||||
|
|
||||||
|
handshakeWriterChan := make(chan interface{});
|
||||||
|
processorHandshakeChan := make(chan interface{});
|
||||||
|
handshakeProcessorChan := make(chan interface{});
|
||||||
|
readerProcessorChan := make(chan *record);
|
||||||
|
|
||||||
|
go new(recordWriter).loop(conn, writeChan, handshakeWriterChan);
|
||||||
|
go recordReader(readerProcessorChan, conn);
|
||||||
|
go new(recordProcessor).loop(readChan, requestChan, handshakeProcessorChan, readerProcessorChan, processorHandshakeChan);
|
||||||
|
go new(serverHandshake).loop(handshakeWriterChan, handshakeProcessorChan, processorHandshakeChan, config);
|
||||||
|
|
||||||
|
return tls;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Listener struct {
|
||||||
|
listener net.Listener;
|
||||||
|
config *Config;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l Listener) Accept() (c net.Conn, err os.Error) {
|
||||||
|
c, err = l.listener.Accept();
|
||||||
|
if err != nil {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = Server(c, l.config);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l Listener) Close() os.Error {
|
||||||
|
return l.listener.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l Listener) Addr() net.Addr {
|
||||||
|
return l.listener.Addr();
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewListener creates a Listener which accepts connections from an inner
|
||||||
|
// Listener and wraps each connection with Server.
|
||||||
|
func NewListener(listener net.Listener, config *Config) (l Listener) {
|
||||||
|
l.listener = listener;
|
||||||
|
l.config = config;
|
||||||
|
return;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user