Beispiel #1
0
func writer(conn net.Conn, outbox chan []byte) {
	defer func() {
		conn.Close()
		clearOutbox(outbox) //incase reader is blocked
	}()

	b := bytes.NewBuffer(nil)

	for {
		select {
		case msg, ok := <-outbox:
			if !ok {
				return
			}
			b.Write(msg)
			for n := len(outbox); n > 0; n-- {
				b.Write(<-outbox)
			}

			conn.SetWriteDeadline(time.Now().Add(5 * time.Second))
			_, err := conn.Write(b.Bytes())
			if err != nil {
				return
			}
			b.Reset()
		}
	}
}
Beispiel #2
0
func serveSPDY(conn net.Conn, srv *http.Server) {
	defer func() {
		if v := recover(); v != nil {
			const size = 4096
			buf := make([]byte, size)
			buf = buf[:runtime.Stack(buf, false)]
			log.Printf("panic serving %v: %v\n%s", conn.RemoteAddr(), v, buf)
		}
	}()

	tlsConn, ok := conn.(*tls.Conn)
	if !ok { // Only allow TLS connections.
		return
	}

	if d := srv.ReadTimeout; d != 0 {
		conn.SetReadDeadline(time.Now().Add(d))
	}
	if d := srv.WriteTimeout; d != 0 {
		conn.SetWriteDeadline(time.Now().Add(d))
	}
	if err := tlsConn.Handshake(); err != nil {
		return
	}

	tlsState := new(tls.ConnectionState)
	*tlsState = tlsConn.ConnectionState()
	proto := tlsState.NegotiatedProtocol
	if fn := srv.TLSNextProto[proto]; fn != nil {
		fn(srv, tlsConn, nil)
	}
	return
}
Beispiel #3
0
func copyBytes(dst, src net.Conn, wg *sync.WaitGroup, writeDeadline, readDeadline time.Duration) {
	defer wg.Done()
	n, err := io.Copy(dst, src)
	if err != nil {
		log.Errorf("proxy i/o error: %v", err)
	}

	if cr, ok := src.(*net.TCPConn); ok {
		cr.CloseRead()
	} else {
		// For TLS connections.
		wto := time.Now().Add(writeDeadline)
		src.SetWriteDeadline(wto)
	}

	if cw, ok := dst.(*net.TCPConn); ok {
		cw.CloseWrite()
	} else {
		// For TLS connections.
		rto := time.Now().Add(readDeadline)
		dst.SetReadDeadline(rto)
	}

	log.Debugf("proxy copied %d bytes %s -> %s", n, src.RemoteAddr(), dst.RemoteAddr())
}
Beispiel #4
0
func (s *Server) updateWriteDeadline(c net.Conn, ctx *RequestCtx, lastDeadlineTime time.Time) time.Time {
	writeTimeout := s.WriteTimeout
	if s.MaxKeepaliveDuration > 0 {
		connTimeout := s.MaxKeepaliveDuration - time.Since(ctx.connTime)
		if connTimeout <= 0 {
			// MaxKeepAliveDuration exceeded, but let's try sending response anyway
			// in 100ms with 'Connection: close' header.
			ctx.SetConnectionClose()
			connTimeout = 100 * time.Millisecond
		}
		if connTimeout < writeTimeout {
			writeTimeout = connTimeout
		}
	}

	// Optimization: update write deadline only if more than 25%
	// of the last write deadline exceeded.
	// See https://github.com/golang/go/issues/15133 for details.
	currentTime := time.Now()
	if currentTime.Sub(lastDeadlineTime) > (writeTimeout >> 2) {
		if err := c.SetWriteDeadline(currentTime.Add(writeTimeout)); err != nil {
			panic(fmt.Sprintf("BUG: error in SetWriteDeadline(%s): %s", writeTimeout, err))
		}
		lastDeadlineTime = currentTime
	}
	return lastDeadlineTime
}
Beispiel #5
0
func createPeerWriter(conn net.Conn) (chan<- []byte, <-chan error) {
	msgChan := make(chan []byte)
	errChan := make(chan error)

	go func() {
		defer log.V(3).Infof("WINSTON: Peer writer goroutine exited\n")
		defer close(errChan)
		// msgChan should be closed by the caller

		for msg := range msgChan {
			// Set a deadline for sending the next message and refresh it before each message
			conn.SetWriteDeadline(time.Now().Add(30 * time.Second))

			err := netWriteUint32(conn, uint32(len(msg)))
			if err != nil {
				errChan <- fmt.Errorf("Could not send byte of new message: '%s'", err)
				break
			}
			_, err = conn.Write(msg)
			if err != nil {
				errChan <- fmt.Errorf("Could not send a message: '%s'", err)
				break
			}
		}
	}()

	return msgChan, errChan
}
Beispiel #6
0
// poll sends a packet and wait for a response. Both operations can timeout, they're retried up to retries times.
func poll(conn net.Conn, toSend []byte, respondBuffer []byte, retries int, timeout time.Duration) (int, error) {
	var err error
	for i := 0; i < retries+1; i++ {
		deadline := time.Now().Add(timeout)

		if err = conn.SetWriteDeadline(deadline); err != nil {
			log.Printf("Couldn't set write deadline. Retrying. Retry %d/%d\n", i, retries)
			continue
		}
		if _, err = conn.Write(toSend); err != nil {
			log.Printf("Couldn't write. Retrying. Retry %d/%d\n", i, retries)
			continue
		}

		deadline = time.Now().Add(timeout)
		if err = conn.SetReadDeadline(deadline); err != nil {
			log.Printf("Couldn't set read deadline. Retrying. Retry %d/%d\n", i, retries)
			continue
		}

		numRead := 0
		if numRead, err = conn.Read(respondBuffer); err != nil {
			log.Printf("Couldn't read. Retrying. Retry %d/%d\n", i, retries)
			continue
		}

		return numRead, nil
	}
	return 0, err
}
Beispiel #7
0
func copyContent(from net.Conn, to net.Conn, complete chan bool, done chan bool, otherDone chan bool) {
	var err error = nil
	var bytes []byte = make([]byte, 256)
	var read int = 0
	for {
		select {
		// If we received a done message from the other goroutine, we exit.
		case <-otherDone:
			complete <- true
			return
		default:

			// Read data from the source connection.
			from.SetReadDeadline(time.Now().Add(time.Second * 5))
			read, err = from.Read(bytes)
			// If any errors occured, write to complete as we are done (one of the
			// connections closed.)
			if err != nil {
				complete <- true
				done <- true
				return
			}
			// Write data to the destination.
			to.SetWriteDeadline(time.Now().Add(time.Second * 5))
			_, err = to.Write(bytes[:read])
			// Same error checking.
			if err != nil {
				complete <- true
				done <- true
				return
			}
		}
	}
}
Beispiel #8
0
// testRacyWrite tests that it is safe to mutate the input Write buffer
// immediately after cancelation has occurred.
func testRacyWrite(t *testing.T, c1, c2 net.Conn) {
	go chunkedCopy(ioutil.Discard, c2)

	var wg sync.WaitGroup
	defer wg.Wait()

	c1.SetWriteDeadline(time.Now().Add(time.Millisecond))
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()

			b1 := make([]byte, 1024)
			b2 := make([]byte, 1024)
			for j := 0; j < 100; j++ {
				_, err := c1.Write(b1)
				copy(b1, b2) // Mutate b1 to trigger potential race
				if err != nil {
					checkForTimeoutError(t, err)
					c1.SetWriteDeadline(time.Now().Add(time.Millisecond))
				}
			}
		}()
	}
}
Beispiel #9
0
func (service *StreamService) serve(conn net.Conn) {
	var data []byte
	var err error
	for {
		if service.readTimeout != nil {
			err = conn.SetReadDeadline(time.Now().Add(service.readTimeout.(time.Duration)))
		}
		if err == nil {
			data, err = receiveDataOverStream(conn)
		}
		if err == nil {
			data = service.Handle(data, &StreamContext{BaseContext: NewBaseContext(), Conn: conn})
			if service.writeTimeout != nil {
				err = conn.SetWriteDeadline(time.Now().Add(service.writeTimeout.(time.Duration)))
			}
			if err == nil {
				err = sendDataOverStream(conn, data)
			}
		}
		if err != nil {
			conn.Close()
			break
		}
	}
}
Beispiel #10
0
// copy Content two-way
func pass(from net.Conn, to net.Conn, complete chan bool, oneSide chan bool, otherSide chan bool) {
	var err error
	var read int
	bytes := make([]byte, 256)

	for {
		select {

		case <-otherSide:
			complete <- true
			return

		default:

			from.SetReadDeadline(time.Now().Add(time.Duration(pConfig.Timeout) * time.Second))
			read, err = from.Read(bytes)
			if err != nil {
				complete <- true
				oneSide <- true
				return
			}

			to.SetWriteDeadline(time.Now().Add(time.Duration(pConfig.Timeout) * time.Second))
			_, err = to.Write(bytes[:read])
			if err != nil {
				complete <- true
				oneSide <- true
				return
			}
		}
	}
}
Beispiel #11
0
func serveSPDY(conn net.Conn, srv *http.Server) {
	defer common.Recover()

	tlsConn, ok := conn.(*tls.Conn)
	if !ok { // Only allow TLS connections.
		return
	}

	if d := srv.ReadTimeout; d != 0 {
		conn.SetReadDeadline(time.Now().Add(d))
	}
	if d := srv.WriteTimeout; d != 0 {
		conn.SetWriteDeadline(time.Now().Add(d))
	}
	if err := tlsConn.Handshake(); err != nil {
		return
	}

	tlsState := new(tls.ConnectionState)
	*tlsState = tlsConn.ConnectionState()
	proto := tlsState.NegotiatedProtocol
	if fn := srv.TLSNextProto[proto]; fn != nil {
		fn(srv, tlsConn, nil)
	}
	return
}
Beispiel #12
0
func (s *session) proxy(c1, c2 net.Conn) error {
	if debug {
		log.Println("Proxy", c1.RemoteAddr(), "->", c2.RemoteAddr())
	}

	atomic.AddInt64(&numProxies, 1)
	defer atomic.AddInt64(&numProxies, -1)

	buf := make([]byte, 65536)
	for {
		c1.SetReadDeadline(time.Now().Add(networkTimeout))
		n, err := c1.Read(buf)
		if err != nil {
			return err
		}

		atomic.AddInt64(&bytesProxied, int64(n))

		if debug {
			log.Printf("%d bytes from %s to %s", n, c1.RemoteAddr(), c2.RemoteAddr())
		}

		if s.rateLimit != nil {
			s.rateLimit(int64(n))
		}

		c2.SetWriteDeadline(time.Now().Add(networkTimeout))
		_, err = c2.Write(buf[:n])
		if err != nil {
			return err
		}
	}
}
Beispiel #13
0
// copy Content two-way
func pass(from net.Conn, to net.Conn, complete chan bool, one_side chan bool, other_side chan bool) {
	var err error = nil
	var bytes []byte = make([]byte, 256)
	var read int = 0

	for {
		select {

		case <-other_side:
			complete <- true
			return

		default:

			from.SetReadDeadline(time.Now().Add(time.Duration(*expire) * time.Second))
			read, err = from.Read(bytes)
			if err != nil {
				complete <- true
				one_side <- true
				return
			}

			to.SetWriteDeadline(time.Now().Add(time.Duration(*expire) * time.Second))
			_, err = to.Write(bytes[:read])
			if err != nil {
				complete <- true
				one_side <- true
				return
			}
		}
	}
}
Beispiel #14
0
func WriteMessage(conn net.Conn, timeout time.Duration, msg *Message) error {
	var handle = &codec.MsgpackHandle{}
	var buf []byte
	var encoder = codec.NewEncoderBytes(&buf, handle)
	err := encoder.Encode(msg)
	if err != nil {
		return err
	}

	length := len(buf)
	if length > DefaultMessageLengthCap {
		return errors.New("message is too long")
	}

	var lengthBuf [2]byte
	binary.BigEndian.PutUint16(lengthBuf[:], uint16(length))

	conn.SetWriteDeadline(time.Now().Add(timeout))
	_, err = conn.Write(lengthBuf[:])
	if err != nil {
		return err
	}

	_, err = io.Copy(conn, bytes.NewBuffer(buf))
	return err
}
Beispiel #15
0
func write(conn net.Conn, content []byte, timeout float64) error {
	if timeout > 0 {
		conn.SetWriteDeadline(time.Now().Add(time.Duration(timeout) * time.Second))
	}
	_, err := conn.Write(content)
	return err
}
Beispiel #16
0
func (c *GsiScanClient) sendRequest(
	conn net.Conn, pkt *transport.TransportPacket, req interface{}) (err error) {

	timeoutMs := c.writeDeadline * time.Millisecond
	conn.SetWriteDeadline(time.Now().Add(timeoutMs))
	return pkt.Send(conn, req)
}
Beispiel #17
0
func NewConn(client *Client, network, addr string, connectTimeout, readTimeout, writeTimeout time.Duration) (*Conn, error) {
	client.CountNewConn++
	var conn net.Conn
	var err error
	if connectTimeout > 0 {
		conn, err = net.DialTimeout(network, addr, connectTimeout)
	} else {
		conn, err = net.Dial(network, addr)
	}
	if err != nil {
		return nil, err
	}
	if readTimeout > 0 {
		conn.SetReadDeadline(time.Now().Add(readTimeout))
	}
	if writeTimeout > 0 {
		conn.SetWriteDeadline(time.Now().Add(writeTimeout))
	}
	this := &Conn{
		Conn:         conn,
		Client:       client,
		ReadTimeout:  readTimeout,
		WriteTimeout: writeTimeout,
	}
	return this, nil
}
Beispiel #18
0
func serveSPDYNoNPN(conn net.Conn, srv *http.Server, version, subversion int) {
	defer common.Recover()

	tlsConn, ok := conn.(*tls.Conn)
	if !ok { // Only allow TLS connections.
		return
	}

	if d := srv.ReadTimeout; d != 0 {
		conn.SetReadDeadline(time.Now().Add(d))
	}
	if d := srv.WriteTimeout; d != 0 {
		conn.SetWriteDeadline(time.Now().Add(d))
	}
	if err := tlsConn.Handshake(); err != nil {
		return
	}

	serverConn, err := NewServerConn(tlsConn, srv, version, subversion)
	if err != nil {
		log.Println(err)
		return
	}
	serverConn.Run()
}
Beispiel #19
0
// Send all the bytes, but respect the upload limit (force delays)
func SockWrite(con net.Conn, buf []byte) (n int, e error) {
	var tosend int
	bw_mutex.Lock()
	TickSent()
	if UploadLimit == 0 {
		tosend = len(buf)
	} else {
		tosend = int(UploadLimit) - ul_bytes_so_far
		if tosend > len(buf) {
			tosend = len(buf)
		} else if tosend < 0 {
			tosend = 0
		}
	}
	ul_bytes_so_far += tosend
	bw_mutex.Unlock()
	if tosend > 0 {
		// Set timeout to prevent thread from getting stuck if the other end does not read
		con.SetWriteDeadline(time.Now().Add(250 * time.Millisecond))
		n, e = con.Write(buf[:tosend])
		bw_mutex.Lock()
		UlBytesTotal += uint64(n)
		ul_bytes_priod += uint64(n)
		bw_mutex.Unlock()
		if e != nil {
			if nerr, ok := e.(net.Error); ok && nerr.Timeout() {
				e = nil
			}
		}
	} else {
		time.Sleep(250 * time.Millisecond)
	}
	return
}
Beispiel #20
0
func tcpSend(conn net.Conn, bytesStream []byte, timeout time.Duration) error {
	if err := conn.SetWriteDeadline(time.Now().Add(timeout)); err != nil {
		return err
	}
	if _, err := conn.Write(bytesStream); err != nil {
		return err
	}
	return nil
}
Beispiel #21
0
func writeMessage(conn net.Conn, m *Message) error {
	conn.SetWriteDeadline(time.Now().Add(idleWriteTimeout))
	if err := json.NewEncoder(conn).Encode(m); err != nil {
		return err
	}
	// Jon wants double newline after each message.
	_, err := conn.Write([]byte("\n\n"))
	return err
}
Beispiel #22
0
func Send(addr string, conn net.Conn, params ...string) error {
	msg := strings.Join(params, " ") + "\n"
	log.Printf("%s <- %s", addr, msg)
	if err := conn.SetWriteDeadline(time.Now().Add(5 * time.Second)); err != nil {
		return err
	}
	_, err := io.WriteString(conn, msg)
	return err
}
Beispiel #23
0
func (self *Http) initConnection(conn net.Conn) {

	now := time.Now()

	readDeadline := now.Add(CONNECTION_READ_TIMEOUT_SECOND * time.Second)
	conn.SetReadDeadline(readDeadline)

	writeDeadline := readDeadline.Add(CONNECTION_READ_TIMEOUT_SECOND * time.Second)
	conn.SetWriteDeadline(writeDeadline)
}
Beispiel #24
0
// testWriteTimeout tests that Write timeouts do not affect Read.
func testWriteTimeout(t *testing.T, c1, c2 net.Conn) {
	go chunkedCopy(c2, rand.New(rand.NewSource(0)))

	c1.SetWriteDeadline(aLongTimeAgo)
	_, err := c1.Write(make([]byte, 1024))
	checkForTimeoutError(t, err)
	if _, err := c1.Read(make([]byte, 1024)); err != nil {
		t.Errorf("unexpected Read error: %v", err)
	}
}
Beispiel #25
0
func (cons *Socket) sendAck(conn net.Conn, success bool) error {
	if cons.acknowledge != "" {
		var err error
		conn.SetWriteDeadline(time.Now().Add(cons.ackTimeout))
		if success {
			_, err = fmt.Fprint(conn, cons.acknowledge)
		} else {
			_, err = fmt.Fprint(conn, "NOT "+cons.acknowledge)
		}
		return err
	}
	return nil
}
Beispiel #26
0
func (this *Server) send(buf []byte, conn net.Conn) error {
	conn.SetWriteDeadline(time.Now().Add(this.connTimeout))
	num, err := conn.Write(buf)
	if err != nil {
		return err
	}

	if num <= 0 {
		return fmt.Errorf("connection write back %d bytes error", num)
	}

	return nil
}
Beispiel #27
0
func setupHeartbeat(c net.Conn) {

	for {
		time.Sleep(1 * time.Second)
		c.SetWriteDeadline(time.Now().Add(3 * time.Second))

		_, err := c.Write([]byte("ping"))
		if err != nil {
			l.Log("Couldn't connect to server. Check your network connection, and run client again.")
			os.Exit(1)
		}
	}
}
Beispiel #28
0
//发送数据 3秒超时删除连接
func (this *MsgBox) SendMsg(key string, conn net.Conn, msg *SimpleMsg) {
	if conn != nil {
		conn.SetWriteDeadline(time.Now().Add(time.Second * 3))
		_, err := conn.Write(msg.ToData()) //包续传先不管
		if err != nil {
			conn.Close()
			this.Conns.Remove(key)
			SysLog.PutLineAsLog(fmt.Sprintf("Msgbox%s SendMsg: %s ERROR:%s", this.BoxId, msg.MsgBody, err.Error()))
		}
	} else {
		this.Conns.Remove(key)
	}
}
Beispiel #29
0
// Write a packet to the conn.
func (w *FixWriter) WritePacket(conn net.Conn, packet []byte) error {
	if w.timeout > 0 {
		conn.SetWriteDeadline(time.Now().Add(w.timeout))
	} else {
		conn.SetWriteDeadline(time.Time{})
	}

	if _, err := conn.Write(packet); err != nil {
		return err
	}

	return nil
}
Beispiel #30
-1
// poolWorker sends data to APNS. A different connection receives the APNS responses.
func poolWorker(wg *sync.WaitGroup, manager ConnManager, requests <-chan workerRequest, maxWaitTime int) {
	defer wg.Done()
	var conn net.Conn = nil
	var err error
	var closed <-chan bool

	lastRequestTime := time.Now()
	for request := range requests {
		curTime := time.Now()
		if conn != nil {
			// Ensure we'll automatically reconnect on a request if we know the connection was closed. This is non-blocking.
			select {
			case <-closed:
				conn = nil
			default:
			}
		}
		if conn != nil && curTime.Sub(lastRequestTime) > CLOSE_TIMEOUT {
			// Close and re-open the connection if the connection has been inactive for over an hour.
			conn.Close()
			conn = nil
			closed = nil
		}
		lastRequestTime = curTime

		if conn == nil {
			// Lazily attempt to open a connection. If that fails, tell the requester that the connection failed.
			conn, closed, err = manager.NewConn()
			if err != nil {
				request.Response <- &PermanentError{Err: err}
				conn = nil
				continue
			}
		}
		deadline := time.Now().Add(time.Duration(maxWaitTime) * time.Second)
		conn.SetWriteDeadline(deadline)
		err := writen(conn, request.Payload)
		if err != nil {
			request.Response <- &TemporaryError{Err: err, Endpoint: conn.RemoteAddr()}
			conn.Close()
			conn = nil
			closed = nil
			continue
		}
		request.Response <- nil
	}
	if conn != nil {
		conn.Close()
		conn = nil
		closed = nil
	}
}