示例#1
0
文件: net.go 项目: mlncn/cothority
// Listen for any host trying to contact him.
// Will launch in a goroutine the srv function once a connection is established
func (t *TcpHost) Listen(addr string, fn func(Conn)) {
	global, _ := cliutils.GlobalBind(addr)
	ln, err := net.Listen("tcp", global)
	if err != nil {
		dbg.Fatal("error listening (host", t.Name(), ")")
	}
	dbg.Lvl3(t.Name(), "Waiting for connections on addr", addr, "..\n")
	for {
		conn, err := ln.Accept()
		if err != nil {
			dbg.Lvl2(t.Name(), "error accepting connection:", err)
			continue
		}
		c := TcpConn{
			Peer: conn.RemoteAddr().String(),
			Conn: conn,
			enc:  gob.NewEncoder(conn),
			dec:  gob.NewDecoder(conn),
			host: t,
		}
		t.peers[conn.RemoteAddr().String()] = &c
		go fn(&c)
	}
}
示例#2
0
// Listen listens for incoming TCP connections.
// It is a non-blocking call that runs in the background.
// It accepts incoming connections and establishes Peers.
// When a peer attempts to connect it must send over its name (as a StringMarshaler),
// as well as its public key.
// Only after that point can be communicated with.
func (h *TCPHost) Listen() error {
	var err error
	dbg.Lvl3("Starting to listen on", h.name)
	address, err := cliutils.GlobalBind(h.name)
	if err != nil {
		dbg.Fatal("Didn't get global binding for", address, err)
	}
	ln, err := net.Listen("tcp4", address)
	if err != nil {
		dbg.Lvl2("failed to listen on", address, ":", err)
		return err
	}
	h.listener = ln
	go func() {
		for {
			var err error
			dbg.Lvl3(h.Name(), "Accepting incoming")
			conn, err := ln.Accept()
			dbg.Lvl3(h.Name(), "Connection request - handling")
			if err != nil {
				dbg.Lvl3("failed to accept connection:", err)
				// if the host has been closed then stop listening
				if atomic.LoadInt64(&h.closed) == 1 {
					return
				}
				continue
			}

			// Read in name of client
			tp := NewTCPConnFromNet(conn)
			var mname StringMarshaler
			err = tp.GetData(&mname)
			if err != nil {
				log.Errorln("failed to establish connection: getting name:", err)
				tp.Close()
				continue
			}
			name := string(mname)

			// create connection
			tp.SetName(name)

			// get and set public key
			suite := h.suite
			pubkey := suite.Point()
			err = tp.GetData(pubkey)
			if err != nil {
				log.Errorln("failed to establish connection: getting pubkey:", err)
				tp.Close()
				continue
			}
			tp.SetPubKey(pubkey)

			// give child the public key
			err = tp.PutData(h.Pubkey)
			if err != nil {
				log.Errorln("failed to send public key:", err)
				continue
			}

			// the connection is now Ready to use
			h.PeerLock.Lock()
			h.Ready[name] = true
			h.peers[name] = tp
			dbg.Lvl3("Connected to child:", tp.Name())
			h.PeerLock.Unlock()

			go func() {
				for {
					data := h.pool.Get().(BinaryUnmarshaler)
					err := tp.GetData(data)

					h.msgchan <- NetworkMessg{Data: data, From: tp.Name(), Err: err}
				}
			}()
		}
	}()
	return nil
}
示例#3
0
// listen for clients connections
func (s *StampListener) ListenRequests() error {
	dbg.Lvl3("Setup StampListener on", s.NameL)
	global, _ := cliutils.GlobalBind(s.NameL)
	var err error
	s.Port, err = net.Listen("tcp4", global)
	if err != nil {
		panic(err)
	}

	go func() {
		for {
			dbg.Lvlf2("Listening to sign-requests: %p", s)
			conn, err := s.Port.Accept()
			if err != nil {
				// handle error
				dbg.Lvl3("failed to accept connection")
				select {
				case w := <-s.waitClose:
					dbg.Lvl3("Closing stamplistener:", w)
					return
				default:
					continue
				}
			}

			dbg.Lvl3("Waiting for connection")
			c := coconet.NewTCPConnFromNet(conn)

			if _, ok := s.Clients[c.Name()]; !ok {
				s.Clients[c.Name()] = c

				go func(co coconet.Conn) {
					for {
						tsm := TimeStampMessage{}
						err := co.GetData(&tsm)
						dbg.Lvlf2("Got data to sign %+v - %+v", tsm, tsm.Sreq)
						if err != nil {
							dbg.Lvlf1("%p Failed to get from child: %s", s.NameL, err)
							co.Close()
							return
						}
						switch tsm.Type {
						default:
							dbg.Lvlf1("Message of unknown type: %v\n", tsm.Type)
						case StampRequestType:
							s.Mux.Lock()
							s.Queue[READING] = append(s.Queue[READING],
								MustReplyMessage{Tsm: tsm, To: co.Name()})
							s.Mux.Unlock()
						case StampClose:
							dbg.Lvl2("Closing connection")
							co.Close()
							return
						case StampExit:
							dbg.Lvl2("Exiting server upon request")
							os.Exit(-1)
						}
					}
				}(c)
			}
		}
	}()

	return nil
}
示例#4
0
// Main entry point of the validation mode
func Validation(keyFile string) {

	// First, retrieve our public / private key pair + address for which it has
	// been created
	kp, addr := readKeyFile(keyFile)
	// Then wait for the connection

	// Accept incoming connections
	global, _ := cliutils.GlobalBind(addr)
	ln, err := net.Listen("tcp", global)
	if err != nil {
		dbg.Fatal("Could not listen for validation:", err)
	}

	var conn net.Conn
	for ; ; conn.Close() {
		dbg.Lvl1("Waiting for verifier connection ...")
		// Accept the one
		conn, err = ln.Accept()
		if err != nil {
			dbg.Fatal("Could not accept an input connection:", err)
		}

		dbg.Lvl1("Verifier connected! Validation in progress...")
		// Craft the message about our system,signs it, and then send the whole
		msg := createSystemPacket()
		signature := signSystemPacket(msg, kp)
		// We also send the size of the signature for the receiver to know how much
		// byte he is expecting
		if err := suite.Write(conn, msg, len(signature), signature); err != nil {
			dbg.Lvl1("Error when writing the system packet to the connection:", err)
			continue
		}

		// Receive the response
		var ack Ack
		if err := suite.Read(conn, &ack); err != nil {
			dbg.Lvl1("Error when reading the response:", err)
		}

		var er string = "Validation is NOT correct, something is wrong about your "
		// All went fine
		dbg.Lvl2("Received code", ack)
		switch ack.Code {
		default:
			dbg.Lvl1("Validation received unknown ACK: type =", ack.Type, "Code =", ack.Code)
			continue
		case SYS_OK:
			dbg.Lvl1("Validation finished successfully! You should receive an email from development team soon.")
		case SYS_WRONG_HOST:
			dbg.Lvl1(er + "HOSTNAME")
		case SYS_WRONG_SOFT:
			dbg.Lvl1(er + "SOFT limits")
		case SYS_WRONG_SIG:
			dbg.Lvl1(er + "signature!")
		case SYS_EXIT:
			dbg.Lvl1("Exiting - need to update to get config.toml")
			os.Exit(1)
		}
	}
}