Ejemplo n.º 1
0
func (s *Server) serveConnection(conn net.Conn) {
	defer conn.Close()
	if s.ReadTimeout != 0 {
		conn.SetReadTimeout(s.ReadTimeout)
	}
	if s.WriteTimeout != 0 {
		conn.SetWriteTimeout(s.WriteTimeout)
	}
	br := bufio.NewReader(conn)
	for {
		t := &transaction{
			server: s,
			conn:   conn,
			br:     br}
		if err := t.prepare(); err != nil {
			if err != os.EOF {
				log.Println("twister: prepare failed", err)
			}
			break
		}

		t.invokeHandler()
		if t.hijacked {
			return
		}
		if err := t.finish(); err != nil {
			log.Println("twister: finish failed", err)
			break
		}
		if t.closeAfterResponse {
			break
		}
	}
}
Ejemplo n.º 2
0
// prepConn() takes a net.Conn and attaches a file descriptor release in its Close method
func (p *Proxy) prepConn(c net.Conn) (net.Conn, os.Error) {
	c.(*net.TCPConn).SetKeepAlive(true)
	err := c.SetReadTimeout(p.config.Timeout)
	if err != nil {
		log.Printf("Error TCP set read timeout: %s\n", err)
		c.Close()
		p.fdl.Unlock()
		return c, err
	}
	err = c.SetWriteTimeout(p.config.Timeout)
	if err != nil {
		log.Printf("Error TCP set write timeout: %s\n", err)
		c.Close()
		p.fdl.Unlock()
		return c, err
	}
	return util.NewRunOnCloseConn(c, func() { p.fdl.Unlock() }), nil
}
Ejemplo n.º 3
0
// Send a request on the connection and hope for a reply.
// Up to cfg.attempts attempts.
func exchange(cfg *dnsConfig, c net.Conn, name string) (*dnsMsg, os.Error) {
	if len(name) >= 256 {
		return nil, &DNSError{Error: "name too long", Name: name}
	}
	out := new(dnsMsg)
	out.id = uint16(rand.Int()) ^ uint16(time.Nanoseconds())
	out.question = []dnsQuestion{
		dnsQuestion{name, dnsTypeMX, dnsClassINET},
	}
	out.recursion_desired = true
	msg, ok := out.Pack()
	if !ok {
		return nil, &DNSError{Error: "internal error - cannot pack message", Name: name}
	}

	for attempt := 0; attempt < cfg.attempts; attempt++ {
		n, err := c.Write(msg)
		if err != nil {
			return nil, err
		}

		c.SetReadTimeout(int64(cfg.timeout) * 1e9) // nanoseconds

		buf := make([]byte, 2000) // More than enough.
		n, err = c.Read(buf)
		if err != nil {
			if e, ok := err.(net.Error); ok && e.Timeout() {
				continue
			}
			return nil, err
		}
		buf = buf[0:n]
		in := new(dnsMsg)
		if !in.Unpack(buf) || in.id != out.id {
			continue
		}
		return in, nil
	}
	var server string
	if a := c.RemoteAddr(); a != nil {
		server = a.String()
	}
	return nil, &DNSError{Error: "no answer from server", Name: name, Server: server, IsTimeout: true}
}
Ejemplo n.º 4
0
func connect(svc ServiceContext, cs chan<- Msg, conn net.Conn) {
	defer logAndClose(conn)

	// Read connect message
	conn.SetReadTimeout(1e9) // 1s
	msg := readMessageOrPanic(conn)
	if msg.Connect == nil {
		panic("Connect message not received!")
	}

	// Check protocol version
	if *msg.Connect.Version != ProtocolVersion {
		// TODO: Send a wrong protocol message, for now just close
		panic(fmt.Sprintf("Wrong protocol version %d, needed %d",
			*msg.Connect.Version, ProtocolVersion))
	}

	// Send connect reply
	msg = makeConnect()
	sendMessageOrPanic(conn, msg)

	// Read login message
	msg = readMessageOrPanic(conn)
	if msg.Login == nil {
		panic("Login message not received!")
	}
	login := msg.Login
	logged_in, reason := startLogin(login)

	// Send login reply
	msg = makeLoginResult(logged_in, reason)
	sendMessageOrPanic(conn, msg)

	cl := newClient(svc, cs, conn, login)
	cs <- addClientMsg{cl}
}
Ejemplo n.º 5
0
Archivo: worker.go Proyecto: reds/goman
func (c *client) worker_loop(n net.Conn) {
	defer n.Close()
	for h, _ := range c.handlers {
		buf := make([]byte, 0)
		buf = append(buf, []byte(h)...)
		buf = append(buf, 0)
		_, e := n.Write(make_req(CAN_DO, []byte(h)))
		if e != nil {
			return
		}
	}
	n.SetReadTimeout(1e9 * 60)
	_, e := n.Write(make_req(GRAB_JOB, []byte{}))
	if e != nil {
		return
	}
	for {
		// worker asks for jobs periodically
		// server will only push a job to a sleeping worker
		cmd, cmd_len, to, e := read_header(n)
		if e != nil {
			return
		}
		if to {
			// timed out, ask for another job
			_, e := n.Write(make_req(GRAB_JOB, []byte{}))
			if e != nil {
				return
			}
			continue
		}
		if cmd == NO_JOB {
			// no jobs, go asleep
			_, e = n.Write(make_req(PRE_SLEEP, []byte{}))
			if e != nil {
				return
			}
			continue
		}

		databuf := make([]byte, cmd_len)
		_, e = io.ReadFull(n, databuf)
		if e != nil {
			return
		}

		switch cmd {
		case NOOP:
			// a wakeup call?
		case ECHO_RES:
		case ERROR:
			//a := bytes.SplitN ( databuf, []byte{0}, 2 )
		case JOB_ASSIGN:
			done := false
			var buf []byte = nil
			for !done {
				buf, done, e = c.do_work(cmd, databuf)
				if e != nil {
					break
				}
			}
			if buf == nil {
				buf = []byte{1, 0}
			}
			_, e = n.Write(make_req(WORK_COMPLETE, buf))
			if e != nil {
				return
			}
		}
		_, e = n.Write(make_req(GRAB_JOB, []byte{}))
		if e != nil {
			return
		}
	}
}