コード例 #1
0
ファイル: telnet.go プロジェクト: mcqueenorama/telnet-chat
// handleConnection is a per-connection go routine that registers the connection
// and starts the go routines that will read/write from the client
func handleConnection(c io.ReadWriteCloser, id string, msgchan chan m.ChatMsg, addchan chan client.Client, rmchan chan client.Client) {

	bufc := bufio.NewReader(c)
	defer c.Close()
	client := client.Client{
		Conn:     c,
		Nickname: promptNick(c, bufc),
		Ch:       make(chan m.ChatMsg),
		Id:       id,
		Kind:     "telnet",
	}

	if strings.TrimSpace(client.Nickname) == "" {
		io.WriteString(c, "Invalid Username\n")
		return
	}

	// Register user
	addchan <- client
	defer func() {
		msgchan <- m.NewChatMessage("system", "User %s left the chat room.\n", client.Nickname)
		log.Info("Connection from %v closed.\n", id)
		rmchan <- client
	}()
	io.WriteString(c, fmt.Sprintf("Welcome, %s!\n\n", client.Nickname))

	msgchan <- m.NewChatMessage("system", "New user %s has joined the chat room.\n", client.Nickname)

	// I/O
	go ReadLinesInto(client, msgchan)
	WriteLinesFrom(client)

}
コード例 #2
0
ファイル: portforward_test.go プロジェクト: rnd-ua/scope
func (pf *fakePortForwarder) PortForward(name string, uid types.UID, port uint16, stream io.ReadWriteCloser) error {
	defer stream.Close()

	var wg sync.WaitGroup

	// client -> server
	wg.Add(1)
	go func() {
		defer wg.Done()

		// copy from stream into a buffer
		received := new(bytes.Buffer)
		io.Copy(received, stream)

		// store the received content
		pf.lock.Lock()
		pf.received[port] = received.String()
		pf.lock.Unlock()
	}()

	// server -> client
	wg.Add(1)
	go func() {
		defer wg.Done()

		// send the hardcoded data to the stream
		io.Copy(stream, strings.NewReader(pf.send[port]))
	}()

	wg.Wait()

	return nil
}
コード例 #3
0
ファイル: seccat.go プロジェクト: BobbWu/go-ipfs
func netcat(c io.ReadWriteCloser) {
	out("piping stdio to connection")

	done := make(chan struct{}, 2)

	go func() {
		n, _ := io.Copy(c, os.Stdin)
		out("sent %d bytes", n)
		done <- struct{}{}
	}()
	go func() {
		n, _ := io.Copy(os.Stdout, c)
		out("received %d bytes", n)
		done <- struct{}{}
	}()

	// wait until we exit.
	sigc := make(chan os.Signal, 1)
	signal.Notify(sigc, syscall.SIGHUP, syscall.SIGINT,
		syscall.SIGTERM, syscall.SIGQUIT)

	select {
	case <-done:
	case <-sigc:
		return
	}

	c.Close()
}
コード例 #4
0
func setflag(c io.ReadWriteCloser) {
	defer c.Close()

	var flag_id string
	fmt.Fprintln(c, "room_id: ")
	_, err := fmt.Fscanln(c, &flag_id)
	if err != nil {
		return
	}
	var cookie string
	fmt.Fprintln(c, "auth_token: ")
	_, err = fmt.Fscanln(c, &cookie)
	if err != nil {
		return
	}
	var flag string
	fmt.Fprintln(c, "flag: ")
	_, err = fmt.Fscanln(c, &flag)
	if err != nil {
		return
	}

	if db.Set(flag_id, []string{cookie, flag}) {
		fmt.Fprintln(c, "set_flag flag_set")
		log.Println("setflag: flag set")
	} else if cookie == db.Get(flag_id)[0] {
		db.Update(flag_id, []string{cookie, flag})
		fmt.Fprintln(c, "setflag: flag_updated")
		log.Println("setflag: flag updated")
	} else {
		fmt.Fprintln(c, "setflag: flag_update_auth_fail")
		log.Println("setflag: auth fail")
	}
}
コード例 #5
0
ファイル: goperconn.go プロジェクト: karrick/goperconn
func (client *Conn) proxy(rwc io.ReadWriteCloser) (bool, error) {
	var closed bool
	for job := range client.jobs {
		if closed {
			job.results <- rillResult{err: ErrClosedConnection{}}
			continue
		}
		switch job.op {
		case _read:
			n, err := rwc.Read(job.data)
			job.results <- rillResult{n, err}
			if err != nil {
				rwc.Close()
				return false, err
			}
		case _write:
			n, err := rwc.Write(job.data)
			job.results <- rillResult{n, err}
			if err != nil {
				rwc.Close()
				return false, err
			}
		case _close:
			closed = true
			err := rwc.Close()
			job.results <- rillResult{err: err}
			return true, err
		}
	}
	return false, nil
}
コード例 #6
0
ファイル: secureconn.go プロジェクト: billyboar/GCSolutions
// New wraps a ReadWriterCloser and uses the underlying reader and writer to
// perform a key exchange and then returns a secured connection.
func New(conn io.ReadWriteCloser) (*SecureConn, error) {
	// Generate key pair
	priv, pub, err := box.GenerateKey(rand.Reader)
	if err != nil {
		return nil, err
	}

	// Send our public key
	// This is done in a goroutine so that read/writes can happen concurrently
	// in the event that the reader and writer are directly connected (for
	// example via io.Pipe)
	done := make(chan error)
	go func() {
		_, err := conn.Write(pub[:])
		done <- err
	}()

	// Read their public key
	key := &[32]byte{}
	if _, err := io.ReadFull(conn, key[:]); err != nil {
		return nil, err
	}
	if err := <-done; err != nil {
		return nil, err
	}

	// Return a secured connection
	return &SecureConn{
		NewSecureReader(conn, priv, key),
		NewSecureWriter(conn, priv, key),
		conn,
		DefaultStreamingChunkSize,
	}, nil
}
コード例 #7
0
ファイル: pipe.go プロジェクト: jsimonetti/tlstun
func Pipe(src io.ReadWriteCloser, dst io.ReadWriteCloser) (int64, int64) {

	var sent, received int64
	var c = make(chan bool)
	var o sync.Once

	close := func() {
		src.Close()
		dst.Close()
		close(c)
	}

	go func() {
		received, _ = io.Copy(src, dst)
		o.Do(close)
	}()

	go func() {
		sent, _ = io.Copy(dst, src)
		o.Do(close)
	}()

	<-c
	return received, sent
}
コード例 #8
0
ファイル: server.go プロジェクト: ProjectNiwl/sagiri
func (srv *Server) HandleClient(raw io.ReadWriteCloser) {
	defer raw.Close()
	/*raw, err := kiss.LLObfsServerHandshake(srv.prv.PublicKey(), raw)
	if err != nil {
		kilog.Debug("directory: client failed LLObfs handshake: %v", err.Error())
		return
	}*/
	var theirKey natrium.EdDSAPublic
	// "verifier" that copies down their public key
	copier := func(haha natrium.EdDSAPublic) bool {
		theirKey = haha
		return true
	}
	sock, err := kiss.KiSSNamedHandshake(srv.prv, copier, raw)
	if err != nil {
		kilog.Debug("directory: client failed KiSS handshake: %v", err.Error())
		return
	}
	defer sock.Close()

	var request clntRequest
	err = struc.Unpack(sock, &request)
	if err != nil {
		kilog.Debug("directory: client sent malformed request: %v", err.Error())
		return
	}
	//fmt.Println(request)
	srv.rqDispatch(sock, request)
}
コード例 #9
0
ファイル: goctl.go プロジェクト: bjc/goctl
func (gc *Goctl) reader(c io.ReadWriteCloser) error {
	defer gc.logger.Info("Connection closed.")
	defer c.Close()

	gc.logger.Info("New connection.")
	for {
		buf, err := Read(c)
		if err != nil {
			gc.logger.Error("Error reading from connection.", "error", err)
			return err
		}

		cmd := strings.Split(string(buf), "\u0000")
		gc.logger.Debug("Got command.", "cmd", cmd)
		var resp string
		if h := gc.handlers[cmd[0]]; h != nil {
			resp = h.Run(gc, cmd[1:])
		} else {
			resp = fmt.Sprintf("ERROR: unknown command: '%s'.", cmd[0])
		}
		gc.logger.Debug("Responding.", "resp", resp)
		Write(c, []byte(resp))
	}
	/* NOTREACHED */
}
コード例 #10
0
func shareEphPubKey(conn io.ReadWriteCloser, locEphPub *[32]byte) (remEphPub *[32]byte, err error) {
	var err1, err2 error
	var wg sync.WaitGroup
	wg.Add(2)

	go func() {
		defer wg.Done()
		_, err1 = conn.Write(locEphPub[:])
	}()

	go func() {
		defer wg.Done()
		remEphPub = new([32]byte)
		_, err2 = io.ReadFull(conn, remEphPub[:])
	}()

	wg.Wait()
	if err1 != nil {
		return nil, err1
	}
	if err2 != nil {
		return nil, err2
	}

	return remEphPub, nil
}
コード例 #11
0
ファイル: downstream.go プロジェクト: jmcarbo/failmail
func (l *Listener) handleConnection(conn io.ReadWriteCloser, received chan<- *ReceivedMessage) {
	defer conn.Close()

	parser := SMTPParser()
	reader := bufio.NewReader(conn)
	writer := bufio.NewWriter(conn)

	session := new(Session)
	session.Start().WriteTo(writer)

	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			l.Printf("error reading from client:", err)
			break
		}

		resp := session.Advance(parser(line))
		resp.WriteTo(writer)

		switch {
		case resp.IsClose():
			return
		case resp.NeedsData():
			resp, msg := session.ReadData(func() (string, error) {
				return reader.ReadString('\n')
			})
			resp.WriteTo(writer)
			if msg != nil {
				received <- msg
			}
		}
	}
}
コード例 #12
0
ファイル: overlord.go プロジェクト: sguzwf/overlord
func (o *Overlord) handleConnection(conn io.ReadWriteCloser) {
	defer conn.Close()
	decoder := codec.NewDecoder(conn, hAsocket)
	encoder := codec.NewEncoder(conn, hAsocket)
	for {
		var msg cocaine.Message
		if err := decoder.Decode(&msg); err != nil {
			log.Printf("protocol decoder error %v", err)
			return
		}
		switch msg.Session {
		case utilitySession:
			if msg.MsgType == handshake {
				log.Println("replying to heartbeat")
				encoder.Encode(msg)
			}
		default:
			o.mu.Lock()
			if ch, ok := o.sessions[msg.Session]; ok {
				select {
				case ch <- &msg:
				case <-time.After(time.Second * 2):
					log.Println("didn't send reply during 2 seconds")
				}
			} else {
				log.Printf("Invalid session %v", msg)
			}
			o.mu.Unlock()
		}
	}
}
コード例 #13
0
ファイル: net_test.go プロジェクト: Gaboose/manet-echo
func assertEcho(t *testing.T, rwc io.ReadWriteCloser, m ma.Multiaddr) {
	str := "test string"
	done := make(chan struct{})
	defer rwc.Close()

	go func() {
		defer close(done)

		_, err := fmt.Fprint(rwc, str)
		if err != nil {
			t.Error(err)
			return
		}

		buf := make([]byte, 256)
		n, err := rwc.Read(buf)
		if err != nil {
			t.Error(err)
			return
		}
		got := string(buf[:n])

		if got != str {
			t.Errorf("expected \"%s\", got \"%s\"", str, got)
		}
	}()

	select {
	case <-done:
	case <-time.After(time.Second):
		t.Errorf("assertEcho: %s timed out", m.String())
	}
}
コード例 #14
0
ファイル: main.go プロジェクト: ProjectNiwl/tinysocks
func handleSocks(clnt io.ReadWriteCloser) {
	defer clnt.Close()
	destin, err := tinysocks.ReadRequest(clnt)
	if err != nil {
		log.Printf("problem while reading SOCKS5 request: %v", err.Error())
		return
	}

	log.Printf("requesting %v", destin)

	remote, err := net.Dial("tcp", destin)
	if err != nil {
		log.Printf("failed to connect to %v (%v)", destin, err.Error())
		tinysocks.CompleteRequest(0x04, clnt)
		return
	}
	tinysocks.CompleteRequest(0x00, clnt)

	log.Printf("succesfully connected to %v", destin)
	defer log.Printf("freed %v", destin)

	// forward between local and remote
	go func() {
		defer clnt.Close()
		defer remote.Close()
		io.Copy(remote, clnt)
	}()
	io.Copy(clnt, remote)
}
コード例 #15
0
ファイル: proxy.go プロジェクト: bitcoinfees/chisel
func (p *Proxy) accept(src io.ReadWriteCloser) {
	p.count++
	cid := p.count
	l := p.Fork("conn#%d", cid)

	l.Debugf("Open")

	if p.client.sshConn == nil {
		l.Debugf("No server connection")
		src.Close()
		return
	}

	remoteAddr := p.remote.RemoteHost + ":" + p.remote.RemotePort
	dst, err := chshare.OpenStream(p.client.sshConn, remoteAddr)
	if err != nil {
		l.Infof("Stream error: %s", err)
		src.Close()
		return
	}

	//then pipe
	s, r := chshare.Pipe(src, dst)
	l.Debugf("Close (sent %d received %d)", s, r)
}
コード例 #16
0
ファイル: session.go プロジェクト: jackc/MailHog-Server
// Accept starts a new SMTP session using io.ReadWriteCloser
func Accept(remoteAddress string, conn io.ReadWriteCloser, storage storage.Storage, messageChan chan *data.Message, hostname string, monkey monkey.ChaosMonkey) {
	defer conn.Close()

	proto := smtp.NewProtocol()
	proto.Hostname = hostname
	var link *linkio.Link
	reader := io.Reader(conn)
	writer := io.Writer(conn)
	if monkey != nil {
		linkSpeed := monkey.LinkSpeed()
		if linkSpeed != nil {
			link = linkio.NewLink(*linkSpeed * linkio.BytePerSecond)
			reader = link.NewLinkReader(io.Reader(conn))
			writer = link.NewLinkWriter(io.Writer(conn))
		}
	}

	session := &Session{conn, proto, storage, messageChan, remoteAddress, false, "", link, reader, writer, monkey}
	proto.LogHandler = session.logf
	proto.MessageReceivedHandler = session.acceptMessage
	proto.ValidateSenderHandler = session.validateSender
	proto.ValidateRecipientHandler = session.validateRecipient
	proto.ValidateAuthenticationHandler = session.validateAuthentication
	proto.GetAuthenticationMechanismsHandler = func() []string { return []string{"PLAIN"} }

	session.logf("Starting session")
	session.Write(proto.Start())
	for session.Read() == true {
		if monkey != nil && monkey.Disconnect != nil && monkey.Disconnect() {
			session.conn.Close()
			break
		}
	}
	session.logf("Session ended")
}
コード例 #17
0
func Copy(a io.ReadWriteCloser, b io.ReadWriteCloser) {
	// setup one-way forwarding of stream traffic
	io.Copy(a, b)
	// and close both connections when a read fails
	a.Close()
	b.Close()
}
コード例 #18
0
ファイル: main.go プロジェクト: aybabtme/deployotron
func handleAgent(ll *log.Log, cc io.ReadWriteCloser) {
	defer cc.Close()
	client := osprocess.New(nil)
	agent := rpc.RepresentAgent(cc, client)

	for i := 0; ; i++ {
		ll.Info("starting program")

		res, err := agent.StartProcess(&rpc.StartProcessReq{
			ProgramName: fmt.Sprintf("echoer v%d i was told to do this by the supervisor", i),
		})
		if err != nil {
			ll.Err(err).Error("couldn't send command to remote agent")
			return
		}
		ll.KV("process.id", res.ProcessID).Info("agent is running program")

		time.Sleep(3 * time.Second)

		ll.Info("stopping program")
		_, err = agent.StopProcess(&rpc.StopProcessReq{ProcessID: res.ProcessID, Timeout: time.Second})
		if err != nil {
			ll.Err(err).Error("couldn't send command to remote agent")
			return
		}
	}

}
コード例 #19
0
ファイル: auth.go プロジェクト: natefinch/claymud
// logs a player in from an incoming connection, creating a player
// in the world if they successfully connect
func Login(rwc io.ReadWriteCloser, ip net.Addr) {
	showTitle(rwc)
	for i := 0; i < retries; i++ {
		user, err := authenticate(rwc, ip)
		switch err {
		case nil:
			world.SpawnPlayer(rwc, user)
			return

		case ErrAuth:
			log.Printf("Failed login from %s", ip)
			_, err = rwc.Write([]byte("Incorrect username or password, please try again\n"))
			if err != nil {
				break
			}
		case ErrDupe:
			ok, err := handleDupe(user, rwc)
			if ok && err == nil {
				kick(user)
				world.SpawnPlayer(rwc, user)
				return
			}
		case ErrNotSetup:
			rwc.Close()
			return
		}
		if err != nil {
			log.Printf("Error during login of user from %s: %s", ip, err)
			return
		}
	}
}
コード例 #20
0
ファイル: secure.go プロジェクト: billyboar/GCSolutions
// secureConnection creates a secure connection from an insecure connection. It
// does this by performing the handshake, then returning an io.ReadWriteCloser
// that can be used to communicate securely.
func secureConnection(conn io.ReadWriteCloser) (io.ReadWriteCloser, error) {

	var priv, pub *[32]byte
	var err error
	pub, priv, err = box.GenerateKey(rand.Reader)
	if err != nil {
		return nil, err
	}

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

	if _, err := io.ReadFull(conn, pub[:]); err != nil {
		return nil, err
	}

	return struct {
		io.Reader
		io.Writer
		io.Closer
	}{
		NewSecureReader(conn, priv, pub),
		NewSecureWriter(conn, priv, pub),
		conn,
	}, nil
}
コード例 #21
0
ファイル: irc.go プロジェクト: fazzzmZozo/botbot-bot
// init initializes the conn to the ircServer and start all the gouroutines
// requires to run ircBot
func (bot *ircBot) init(conn io.ReadWriteCloser) {
	glog.Infoln("Init bot", bot)

	quit := make(chan struct{})
	receive := make(chan string)

	go bot.readSocket(quit, receive, conn)

	// Listen for incoming messages in background thread
	go bot.listenSendMonitor(quit, receive, conn)

	go func(bot *ircBot, conn io.Closer) {
		for {
			select {
			case <-bot.closing:
				err := conn.Close()
				if err != nil {
					glog.Errorln("An error occured while closing the conn of", bot, err)
				}
				close(quit)
				return
			}
		}
	}(bot, conn)

	bot.RLock()
	if bot.serverPass != "" {
		bot.SendRaw("PASS " + bot.serverPass)
	}
	bot.RUnlock()

	bot.SendRaw("PING Bonjour")
}
コード例 #22
0
ファイル: graphiteTcp.go プロジェクト: rayleyva/MetricBase
func (g *GraphiteTcpServer) handleConnection(conn io.ReadWriteCloser) {
	scanner := bufio.NewScanner(conn)
	defer conn.Close()

	// Create a channel for the metrics
	addChan := make(chan metrics.Metric, 1000)
	g.backend.AddMetricChan(addChan)
	defer close(addChan)

	for scanner.Scan() {
		// PARSE METRIC LINES
		//err, m :=
		err, m := parseGraphiteLine(scanner.Text())
		if err == nil {
			// Send parsed metric to the back-end
			addChan <- m
		} else {
			conn.Write([]byte(err.Error()))
		}
	}

	if err := scanner.Err(); err != nil {
		fmt.Printf("Error while parsing text: %v", err)
	}
}
コード例 #23
0
func getflag(c io.ReadWriteCloser) {
	defer c.Close()
	var flag_id string
	fmt.Fprintln(c, "flag_id: ")
	_, err := fmt.Fscanln(c, &flag_id)
	if err != nil {
		return
	}
	var cookie string
	fmt.Fprintln(c, "token_id: ")
	_, err = fmt.Fscanln(c, &cookie)
	if err != nil {
		return
	}
	entry := db.Get(flag_id)
	if entry == nil {
		fmt.Fprintln(c, "flagval: no_entry_exists")
		log.Println("getflag: request for non-existant entry")
	} else if cookie == entry[0] {
		fmt.Fprintln(c, "flagval:", entry[1])
		log.Println("getflag: got")
	} else {
		fmt.Fprintln(c, "flagval: getflag_auth_fail")
		log.Println("getflag: auth fail")
	}
	return
}
コード例 #24
0
ファイル: telnetd.go プロジェクト: kissthink/gobox
func serve(c io.ReadWriteCloser, call []string) {
	defer c.Close()
	e := serveExec(c, call)
	if e != nil {
		common.FDumpError(c, e)
	}
}
コード例 #25
0
ファイル: client.go プロジェクト: AssertSelenium/terraform
// NewClient creates a client from an already-open connection-like value.
// Dial is typically used instead.
func NewClient(conn io.ReadWriteCloser) (*Client, error) {
	// Create the yamux client so we can multiplex
	mux, err := yamux.Client(conn, nil)
	if err != nil {
		conn.Close()
		return nil, err
	}

	// Connect to the control stream.
	control, err := mux.Open()
	if err != nil {
		mux.Close()
		return nil, err
	}

	// Create the broker and start it up
	broker := newMuxBroker(mux)
	go broker.Run()

	// Build the client using our broker and control channel.
	return &Client{
		broker:  broker,
		control: rpc.NewClient(control),
	}, nil
}
コード例 #26
0
ファイル: ots.go プロジェクト: yinqiwen/gotoolkit
func ProcessTroubleShooting(rwc io.ReadWriteCloser) {
	data := make([]byte, 0)
	buf := make([]byte, 1024)
	for {
		n, err := rwc.Read(buf)
		if nil != err {
			break
		}
		if len(data) == 0 {
			data = buf[0:n]
		} else {
			data = append(data, buf[0:n]...)
		}
		if len(data) > 1024 {
			fmt.Fprintf(rwc, "Too long command from input.")
			break
		}
		i := bytes.IndexByte(data, '\n')
		if -1 == i {
			continue
		}
		line := strings.TrimSpace(string(data[0:i]))
		data = data[i+1:]
		if len(line) == 0 {
			continue
		}

		err = Handle(line, rwc)
		if err == io.EOF {
			break
		}
	}
	rwc.Close()
}
コード例 #27
0
ファイル: server.go プロジェクト: devendraPSL/terraform-api
// ServeConn runs a single connection.
//
// ServeConn blocks, serving the connection until the client hangs up.
func (s *Server) ServeConn(conn io.ReadWriteCloser) {
	// First create the yamux server to wrap this connection
	mux, err := yamux.Server(conn, nil)
	if err != nil {
		conn.Close()
		log.Printf("[ERR] plugin: %s", err)
		return
	}

	// Accept the control connection
	control, err := mux.Accept()
	if err != nil {
		mux.Close()
		log.Printf("[ERR] plugin: %s", err)
		return
	}

	// Create the broker and start it up
	broker := newMuxBroker(mux)
	go broker.Run()

	// Use the control connection to build the dispenser and serve the
	// connection.
	server := rpc.NewServer()
	server.RegisterName("Dispenser", &dispenseServer{
		ProviderFunc:    s.ProviderFunc,
		ProvisionerFunc: s.ProvisionerFunc,

		broker: broker,
	})
	server.ServeConn(control)
}
コード例 #28
0
ファイル: client.go プロジェクト: Nightgunner5/gogame
func client(username string, server io.ReadWriteCloser) {
	log.Print("Connected to server")
	defer server.Close()
	defer log.Print("Server disconnected")

	buf := bufio.NewWriter(server)
	encode, decode := gob.NewEncoder(buf), gob.NewDecoder(server)

	var handshake Handshake
	if err := encode.Encode(handshake); err != nil {
		log.Printf("Error while sending handshake: %s", err)
		return
	}

	send := make(chan *packet.Packet)
	defer close(send)

	clientpkg.Network = send

	go clientEncode(encode, buf, send)
	go clientDecode(decode)

	go keepAlive(send)

	clientpkg.Main()
}
コード例 #29
0
ファイル: main.go プロジェクト: Ryan-Ng/kcptun
func handleClient(p1, p2 io.ReadWriteCloser) {
	log.Println("stream opened")
	defer log.Println("stream closed")
	defer p1.Close()
	defer p2.Close()

	// start tunnel
	p1die := make(chan struct{})
	go func() {
		io.Copy(p1, p2)
		close(p1die)
	}()

	p2die := make(chan struct{})
	go func() {
		io.Copy(p2, p1)
		close(p2die)
	}()

	// wait for tunnel termination
	select {
	case <-p1die:
	case <-p2die:
	}
}
コード例 #30
0
ファイル: kiss_handshake.go プロジェクト: ProjectNiwl/sagiri
func kissFinishHandshake(eph_priv natrium.ECDHPrivate,
	packaged kissSegment, check Verifier,
	transport io.ReadWriteCloser) (*kissContext, error) {
	signal := make(chan error, 1)
	// spawn new thread to prevent deadlock
	go func() {
		err := struc.Pack(transport, &packaged)
		if err != nil {
			fmt.Println(err.Error())
			transport.Close()
			signal <- err
		} else {
			signal <- nil
		}
	}()

	// wait for other end
	var their_hello kissSegment
	err := struc.Unpack(transport, &their_hello)
	if err != nil {
		return nil, ErrFailHello
	}

	// wait for our end to finish (do not want to stomp with our response)
	err = <-signal
	if err != nil {
		return nil, err
	}

	// different types of hello
	var their_eph_pub natrium.ECDHPublic
	switch their_hello.Msgtyp {
	case kiss_AHLO:
		if check != nil {
			return nil, ErrWrongHello
		}
		their_eph_pub = their_hello.Payload
	case kiss_NHLO:
		var mss kissNamedHello
		err := struc.Unpack(bytes.NewBuffer(their_hello.Payload), &mss)
		if err != nil {
			fmt.Println(err.Error())
			return nil, ErrBadHello
		}
		err = mss.Ltm_key.Verify(mss.Eph_key, mss.Signat)
		if err != nil {
			fmt.Println(err.Error())
			return nil, ErrBadHello
		}
		if check != nil && check(mss.Ltm_key) == false {
			return nil, ErrBadExchange
		}
		their_eph_pub = mss.Eph_key
	default:
		fmt.Println(their_hello)
		return nil, ErrBadHello
	}

	return kissGenerateCtx(transport, eph_priv, their_eph_pub), nil
}