Example #1
0
File: actions.go Project: wwek/ncgo
//throwBytes chucks bytes at the remote server then listens for a response
func throwBytes(conn io.ReadWriter, count uint64) error {
	var writeBytes uint64
	var b []byte
	buff := make([]byte, 128)
	for writeBytes < count {
		if (count - writeBytes) >= uint64(len(dataBlock)) {
			b = dataBlock
		} else {
			b = dataBlock[0:(count - writeBytes)]
		}
		n, err := conn.Write(b)
		if err != nil {
			return err
		}
		writeBytes += uint64(n)
	}
	//read the response
	n, err := conn.Read(buff)
	if err != nil {
		return err
	}
	if n == 0 {
		return fmt.Errorf("Failed to get OK on upload")
	}
	if !strings.HasPrefix(string(buff[0:n]), "OK ") {
		return fmt.Errorf("Failed to get OK on upload")
	}
	return nil
}
Example #2
0
func (r *Receiver) handleTransfer(conn io.ReadWriter) (
	transfer.TransferResults, error,
) {
	if _, err := conn.Write([]byte("ok")); err != nil {
		return transfer.TransferResults{}, err
	}

	res := transfer.TransferResults{}
	buffer := make([]byte, 1024)

	startTime := time.Now()
	for {
		n, err := conn.Read(buffer)
		if err != nil { // done reading
			break
		}

		res.BytesSent += uint32(n)
		res.Checksum = crc32.Update(res.Checksum, crc32.IEEETable, buffer)
	}
	endTime := time.Now()

	res.Duration = endTime.Sub(startTime)

	return res, nil
}
Example #3
0
func ClientHandshake(stream io.ReadWriter, local Certificate) (*Transport, error) {
	pub, priv, err := GenerateExchangeKey()

	if err != nil {
		return nil, err
	}

	if _, err = stream.Write(pub); err != nil {
		return nil, err
	}

	theirkey := make([]byte, PublicKeySize)

	if _, err = stream.Read(theirkey); err != nil {
		return nil, err
	}

	cipher1, cipher2, err := CreateExchangedCipher(theirkey, priv)

	if err != nil {
		return nil, err
	}

	macKey, err := GenerateMACKey()

	if err != nil {
		return nil, err
	}

	encryptedMACKey := make([]byte, MACSize)

	cipher1.XORKeyStream(encryptedMACKey, macKey)

	if _, err = stream.Write(encryptedMACKey); err != nil {
		return nil, err
	}

	transport := new(Transport)

	transport.stream = stream
	transport.macKey = macKey

	transport.readCipher = cipher2
	transport.writeCipher = cipher1

	if err := sendCertificate(transport, local); err != nil {
		return nil, err
	}

	remote, err := requireCertificate(transport)

	if err != nil {
		return nil, err
	}

	transport.local = local
	transport.remote = remote

	return transport, nil
}
Example #4
0
// dnsRoundTripUDP implements the dnsRoundTrip interface for RFC 1035's
// "UDP usage" transport mechanism. c should be a packet-oriented connection,
// such as a *UDPConn.
func dnsRoundTripUDP(c io.ReadWriter, query *dnsMsg) (*dnsMsg, error) {
	b, ok := query.Pack()
	if !ok {
		return nil, errors.New("cannot marshal DNS message")
	}
	if _, err := c.Write(b); err != nil {
		return nil, err
	}

	b = make([]byte, 512) // see RFC 1035
	for {
		n, err := c.Read(b)
		if err != nil {
			return nil, err
		}
		resp := &dnsMsg{}
		if !resp.Unpack(b[:n]) || !resp.IsResponseTo(query) {
			// Ignore invalid responses as they may be malicious
			// forgery attempts. Instead continue waiting until
			// timeout. See golang.org/issue/13281.
			continue
		}
		return resp, nil
	}
}
Example #5
0
func verifyPipe(t *testing.T, a, b io.ReadWriter) {
	mes := make([]byte, 1024)
	rand.Read(mes)
	go func() {
		b.Write(mes)
		a.Write(mes)
	}()

	buf := make([]byte, len(mes))
	n, err := a.Read(buf)
	if err != nil {
		t.Fatal(err)
	}
	if n != len(buf) {
		t.Fatal("failed to read enough")
	}

	if string(buf) != string(mes) {
		t.Fatal("somehow read wrong message")
	}

	n, err = b.Read(buf)
	if err != nil {
		t.Fatal(err)
	}
	if n != len(buf) {
		t.Fatal("failed to read enough")
	}

	if string(buf) != string(mes) {
		t.Fatal("somehow read wrong message")
	}
}
Example #6
0
func negotiateMethod(c Context, rw io.ReadWriter) {
	rw.Write(methodRequest(proxy.MethodNoPassword))
	if _, err := rw.Read(make([]byte, 3)); err != nil {
		c.Error(err)
	}
	return
}
Example #7
0
func echoOnce(rw io.ReadWriter) error {
	buf := make([]byte, 256)
	n, err := rw.Read(buf)
	if err != nil {
		return err
	}
	_, err = rw.Write(buf[:n])
	return err
}
Example #8
0
func ServerHandshake(stream io.ReadWriter, local Certificate) (*Transport, error) {
	pub, priv, err := GenerateExchangeKey()

	if err != nil {
		return nil, err
	}

	theirkey := make([]byte, PublicKeySize)

	if _, err = stream.Read(theirkey); err != nil {
		return nil, err
	}

	if _, err = stream.Write(pub); err != nil {
		return nil, err
	}

	cipher1, cipher2, err := CreateExchangedCipher(theirkey, priv)

	if err != nil {
		return nil, err
	}

	macKey := make([]byte, MACSize)

	if n, err := stream.Read(macKey); err != nil {
		return nil, err
	} else if n < MACSize {
		return nil, MacKeyTooSmallError
	}

	cipher1.XORKeyStream(macKey, macKey)

	transport := new(Transport)

	transport.stream = stream
	transport.macKey = macKey

	transport.readCipher = cipher1
	transport.writeCipher = cipher2

	remote, err := requireCertificate(transport)

	if err != nil {
		return nil, err
	}

	if err := sendCertificate(transport, local); err != nil {
		return nil, err
	}

	transport.local = local
	transport.remote = remote

	return transport, nil
}
Example #9
0
// exchangeKeys performs a key exchange with a remote peer
// and returns peer's public key after successfull exchange.
func exchangeKeys(conn io.ReadWriter, pub *[32]byte) (*[32]byte, error) {
	var ppub [32]byte
	if _, err := conn.Write(pub[:]); err != nil {
		return nil, err
	}
	if _, err := conn.Read(ppub[:]); err != nil {
		return nil, err
	}
	return &ppub, nil
}
Example #10
0
// exchangeKeys performs the exchange of the keys
// by writing the public key into the data stream first and
// then reading the shared key from the data stream.
func exchangeKeys(pub, peerPub *[32]byte, rw io.ReadWriter) error {
	if _, err := rw.Write(pub[:]); err != nil {
		return err
	}

	if _, err := rw.Read(peerPub[:]); err != nil {
		return err
	}

	return nil
}
Example #11
0
func (p *Proxy) pipe(src, dst io.ReadWriter) {
	islocal := src == p.lconn

	var dataDirection string
	if islocal {
		dataDirection = ">>> %d bytes sent%s"
	} else {
		dataDirection = "<<< %d bytes recieved%s"
	}

	var byteFormat string
	if p.OutputHex {
		byteFormat = "%x"
	} else {
		byteFormat = "%s"
	}

	//directional copy (64k buffer)
	buff := make([]byte, 0xffff)
	for {
		n, err := src.Read(buff)
		if err != nil {
			p.err("Read failed '%s'\n", err)
			return
		}
		b := buff[:n]

		//execute match
		if p.Matcher != nil {
			p.Matcher(b)
		}

		//execute replace
		if p.Replacer != nil {
			b = p.Replacer(b)
		}

		//show output
		p.Log.Debug(dataDirection, n, "")
		p.Log.Trace(byteFormat, b)

		//write out result
		n, err = dst.Write(b)
		if err != nil {
			p.err("Write failed '%s'\n", err)
			return
		}
		if islocal {
			p.sentBytes += uint64(n)
		} else {
			p.receivedBytes += uint64(n)
		}
	}
}
Example #12
0
// CopyToWebsocket copies pipe data to/from a websocket.  It blocks.
func (p *pipe) CopyToWebsocket(end io.ReadWriter, conn *websocket.Conn) error {
	p.mtx.Lock()
	if p.closed {
		p.mtx.Unlock()
		return nil
	}
	p.wg.Add(1)
	p.mtx.Unlock()
	defer p.wg.Done()

	errors := make(chan error, 1)

	// Read-from-UI loop
	go func() {
		for {
			_, buf, err := conn.ReadMessage() // TODO type should be binary message
			if err != nil {
				errors <- err
				return
			}

			if _, err := end.Write(buf); err != nil {
				errors <- err
				return
			}
		}
	}()

	// Write-to-UI loop
	go func() {
		buf := make([]byte, 1024)
		for {
			n, err := end.Read(buf)
			if err != nil {
				errors <- err
				return
			}

			if err := conn.WriteMessage(websocket.BinaryMessage, buf[:n]); err != nil {
				errors <- err
				return
			}
		}
	}()

	// block until one of the goroutines exits
	// this convoluted mechanism is to ensure we only close the websocket once.
	select {
	case err := <-errors:
		return err
	case <-p.quit:
		return nil
	}
}
Example #13
0
func (us *UnixSock) processBuffer(fd io.ReadWriter) {
	var buf [1024]byte

	for {
		n, err := fd.Read(buf[0:])
		if err != nil || n == 0 {
			break
		}
		us.data <- pipe.NewSimpleChunk(buf[0:n])
	}
}
Example #14
0
func runEcho(fd io.ReadWriter, done chan<- int) {
	var buf [1024]byte

	for {
		n, err := fd.Read(buf[0:])
		if err != nil || n == 0 || string(buf[:n]) == "END" {
			break
		}
		fd.Write(buf[0:n])
	}
	done <- 1
}
Example #15
0
func runEcho(fd io.ReadWriter, done chan<- int) {
	var buf [1024]byte;

	for {
		n, err := fd.Read(&buf);
		if err != nil || n == 0 {
			break
		}
		fd.Write(buf[0:n]);
	}
	done <- 1;
}
Example #16
0
func exchangeKeys(pub *[32]byte, conn io.ReadWriter) (*[32]byte, error) {
	_, err := conn.Write(pub[:])
	if err != nil {
		return nil, err
	}

	otherPub := [32]byte{}
	_, err = conn.Read(otherPub[:])
	if err != nil {
		return nil, err
	}
	return &otherPub, nil
}
Example #17
0
// submitTPMRequest sends a structure to the TPM device file and gets results
// back, interpreting them as a new provided structure.
func submitTPMRequest(rw io.ReadWriter, tag uint16, ord uint32, in []interface{}, out []interface{}) (uint32, error) {
	if rw == nil {
		return 0, errors.New("nil TPM handle")
	}

	ch := commandHeader{tag, 0, ord}
	inb, err := packWithHeader(ch, in)
	if err != nil {
		return 0, err
	}

	if _, err := rw.Write(inb); err != nil {
		return 0, err
	}

	// Try to read the whole thing, but handle the case where it's just a
	// ResponseHeader and not the body, since that's what happens in the error
	// case.
	var rh responseHeader
	rhSize := binary.Size(rh)
	outb := make([]byte, maxTPMResponse)
	outlen, err := rw.Read(outb)
	if err != nil {
		return 0, err
	}

	// Resize the buffer to match the amount read from the TPM.
	outb = outb[:outlen]
	if err := unpack(outb[:rhSize], []interface{}{&rh}); err != nil {
		return 0, err
	}

	// Check success before trying to read the rest of the result.
	// Note that the command tag and its associated response tag differ by 3,
	// e.g., tagRQUCommand == 0x00C1, and tagRSPCommand == 0x00C4.
	if rh.Res != 0 {
		return rh.Res, tpmError(rh.Res)
	}

	if rh.Tag != ch.Tag+3 {
		return 0, errors.New("inconsistent tag returned by TPM. Expected " + strconv.Itoa(int(ch.Tag+3)) + " but got " + strconv.Itoa(int(rh.Tag)))
	}

	if rh.Size > uint32(rhSize) {
		if err := unpack(outb[rhSize:], out); err != nil {
			return 0, err
		}
	}

	return rh.Res, nil
}
Example #18
0
// DefaultInteractive is the default server selection prompt for users during
// session forward.
func DefaultInteractive(comm io.ReadWriter, session *Session) (string, error) {
	remotes := session.Remotes

	fmt.Fprintf(comm, "Welcome to sshmux, %s\r\n", session.Conn.User())
	for i, v := range remotes {
		fmt.Fprintf(comm, "    [%d] %s\r\n", i, v)
	}

	// Beware, nasty comm parsing loop
loop:
	for {
		fmt.Fprintf(comm, "Please select remote server: ")
		var buf []byte
		b := make([]byte, 1)
		var (
			n   int
			err error
		)
		for {
			if err != nil {
				return "", err
			}
			n, err = comm.Read(b)
			if n == 1 {
				fmt.Fprintf(comm, "%s", b)
				switch b[0] {
				case '\r':
					fmt.Fprintf(comm, "\r\n")
					res, err := strconv.ParseInt(string(buf), 10, 64)
					if err != nil {
						fmt.Fprintf(comm, "comm not a valid integer. Please try again\r\n")
						continue loop
					}
					if int(res) >= len(remotes) || res < 0 {
						fmt.Fprintf(comm, "No such server. Please try again\r\n")
						continue loop
					}

					return remotes[int(res)], nil
				case 0x03:
					fmt.Fprintf(comm, "\r\nGoodbye\r\n")
					return "", errors.New("user terminated session")
				}

				buf = append(buf, b[0])
			}
		}
	}
}
Example #19
0
func (s *Sender) handshake(conn io.ReadWriter) error {
	msgBytes := make([]byte, 16)
	n, err := conn.Read(msgBytes)
	if err != nil {
		return err
	}

	msg := string(msgBytes[:n])
	if msg == "ok" {
		return nil
	} else if msg == "i-am-busy" {
		return ErrBusy
	} else {
		return fmt.Errorf("unrecognized server response `%s`", msg)
	}
}
Example #20
0
// echo server on top of a generic io.ReadWriter. Reads from the reader,
// and writes received data back to the writer. To implement secure echo,
// rw must be composed of a secure reader and writer, as produced by
// serverHandshake.
func echo(rw io.ReadWriter) error {
	var (
		n   int
		err error
	)
	buf := make([]byte, msglen)

	for {
		if n, err = rw.Read(buf); err != nil {
			return err
		}
		if _, err := rw.Write(buf[:n]); err != nil {
			return err
		}
	}
}
Example #21
0
func WriteFileHandler(parameters string, connection io.ReadWriter) {

	segments := strings.Split(parameters, " ")

	if len(segments) != 2 {
		log.Println("Invalid put command formatting")
	}

	lengtha, _ := strconv.Atoi(segments[1])
	fileName := segments[0]

	log.Printf("Receive file '%s' (length = %d)", fileName, lengtha)

	file, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0)
	if err != nil {
		log.Printf("Failed to open file for writing: %s\n", err)
		return
	}

	common.WriteString(connection, "ok")

	buffer := make([]byte, 1024)

	for {

		// Read from socket
		n, err := connection.Read(buffer)
		if err != nil {
			log.Println("Failed to read data from socket; abandoning transfer")
			break
		}

		// Read into buffer
		_, err = file.Write(buffer[:n])

		lengtha = lengtha - n
		if lengtha == 0 {
			log.Println("Transfer completed")
			break
		}
	}

	common.WriteString(connection, "ok")
	file.Close()
}
Example #22
0
File: mse_test.go Project: cenk/mse
func testRws(a, b io.ReadWriter) error {
	data := []byte("ABCD")
	go a.Write(data)

	buf := make([]byte, 10)
	n, err := b.Read(buf)
	if err != nil {
		return err
	}
	if n != 4 {
		return fmt.Errorf("n must be 4, not %d", n)
	}
	if !bytes.Equal(buf[:n], data) {
		return fmt.Errorf("invalid data received: %s", hex.EncodeToString(buf[:n]))
	}

	return nil
}
Example #23
0
func (s *Sender) handshake(conn io.ReadWriter) (uint16, error) {
	msgBytes := make([]byte, 16)
	n, err := conn.Read(msgBytes)
	if err != nil {
		return 0, err
	}

	msg := string(msgBytes[:n])
	var iperfPort uint16
	_, err = fmt.Sscanf(msg, "ok - %d", &iperfPort)
	if err != nil {
		if msg == "i-am-busy" {
			return 0, ErrBusy
		} else {
			return 0, fmt.Errorf("unrecognized server response `%s`: %s", msg, err)
		}
	}

	return iperfPort, nil
}
Example #24
0
func ModemSend(c io.ReadWriter, data []byte) error {
	oBuffer := make([]byte, 1)

	if _, err := c.Read(oBuffer); err != nil {
		return err
	}

	if oBuffer[0] == POLL {
		var blocks uint8 = uint8(len(data) / LONG_PACKET_PAYLOAD_LEN)
		if len(data) > int(int(blocks)*int(LONG_PACKET_PAYLOAD_LEN)) {
			blocks++
		}

		failed := 0
		var currentBlock uint8 = 0
		for currentBlock < blocks && failed < 10 {
			if int(int(currentBlock+1)*int(LONG_PACKET_PAYLOAD_LEN)) > len(data) {
				sendBlock(c, currentBlock+1, data[int(currentBlock)*int(LONG_PACKET_PAYLOAD_LEN):])
			} else {
				sendBlock(c, currentBlock+1, data[int(currentBlock)*int(LONG_PACKET_PAYLOAD_LEN):(int(currentBlock)+1)*int(LONG_PACKET_PAYLOAD_LEN)])
			}

			if _, err := c.Read(oBuffer); err != nil {
				return err
			}

			if oBuffer[0] == ACK {
				currentBlock++
			} else {
				failed++
			}
		}

		if _, err := c.Write([]byte{EOT}); err != nil {
			return err
		}
	}

	return nil
}
func testSecureSessionMessage(conn1, conn2 io.ReadWriter) error {
	pt := []byte("hello peer!")
	nw, err := conn1.Write(pt)
	if err != nil {
		return fmt.Errorf("write error: %s", err)
	}

	ptr := make([]byte, len(pt))
	nr, err := conn2.Read(ptr)
	if err != nil {
		return fmt.Errorf("read error: %s", err)
	}

	if nr != nw {
		return fmt.Errorf("bytes read not equal to bytes written: %d != %d", nr, nw)
	}

	if !bytes.Equal(ptr, pt) {
		return fmt.Errorf("message read not equal to message written: %q != %q", ptr, pt)
	}

	return nil
}
Example #26
0
func receivePacket(c io.ReadWriter) ([]byte, error) {
	oBuffer := make([]byte, 1)
	dBuffer := make([]byte, LONG_PACKET_PAYLOAD_LEN)

	if _, err := c.Read(oBuffer); err != nil {
		return nil, err
	}
	pType := oBuffer[0]

	if pType == EOT {
		return nil, nil
	}

	var packetSize int
	switch pType {
	case SOH:
		packetSize = SHORT_PACKET_PAYLOAD_LEN
		break
	case STX:
		packetSize = LONG_PACKET_PAYLOAD_LEN
		break
	}

	if _, err := c.Read(oBuffer); err != nil {
		return nil, err
	}
	packetCount := oBuffer[0]

	if _, err := c.Read(oBuffer); err != nil {
		return nil, err
	}
	inverseCount := oBuffer[0]

	if packetCount > inverseCount || inverseCount+packetCount != 255 {
		if _, err := c.Write([]byte{NAK}); err != nil {
			return nil, err
		}
		return nil, InvalidPacket
	}

	received := 0
	var pData bytes.Buffer
	for received < packetSize {
		n, err := c.Read(dBuffer)
		if err != nil {
			return nil, err
		}

		received += n
		pData.Write(dBuffer[:n])
	}

	var crc uint16
	if _, err := c.Read(oBuffer); err != nil {
		return nil, err
	}
	crc = uint16(oBuffer[0])

	if _, err := c.Read(oBuffer); err != nil {
		return nil, err
	}
	crc <<= 8
	crc |= uint16(oBuffer[0])

	// Calculate CRC
	crcCalc := CRC16(pData.Bytes())
	if crcCalc != crc {
		if _, err := c.Write([]byte{NAK}); err != nil {
			return nil, err
		}
	}

	if _, err := c.Write([]byte{ACK}); err != nil {
		return nil, err
	}

	return pData.Bytes(), nil
}
Example #27
0
// HandshakeClient establishes connection with the server making sure
// they both are in sync.
func HandshakeClient(conn io.ReadWriter, debug bool) error {
	if tracing {
		defer trace.End(trace.Begin(""))
	}

	buf1byte := make([]byte, 1)

	if _, err := rand.Read(buf1byte); err != nil {
		log.Errorf("HandshakeClient: Could not read a random byte due to: %v", err)
	}

	pos := incrementByte(buf1byte[0])

	// set the read deadline for timeout
	// this has no effect on windows as the deadline is set at port open time

	log.Debug("HandshakeClient: Sending syn.")
	conn.Write([]byte{flagSyn, pos})
	pos = incrementByte(pos)

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

	if buf1byte[0] != flagAck {
		if buf1byte[0] == flagNak {
			log.Debugf("HandshakeClient: Server didn't accept sync. Trying one more time.")
			return &HandshakeError{
				msg: "Server declined handshake request",
			}
		}
		return &HandshakeError{
			msg: fmt.Sprintf("Unexpected server response: %d", buf1byte[0]),
		}
	}

	// read response sync position.
	if _, err := conn.Read(buf1byte); err != nil {
		return err
	}

	if buf1byte[0] != pos {
		log.Debugf("HandshakeClient: Unexpected byte pos for SynAck: %x, expected: %x", buf1byte[0], pos)
		return &HandshakeError{
			msg: fmt.Sprintf("Unexpected sync position response: %d", buf1byte[0]),
		}
	}

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

	log.Debug("HandshakeClient: Sending ack.")

	if !debug {
		conn.Write([]byte{flagAck, incrementByte(buf1byte[0])})
	} else {
		conn.Write([]byte{flagDebugAck, incrementByte(buf1byte[0])})
		// Verify packet length handling works.  We're going to send a known stream
		// of data to the container and it will echo it back.  Verify the sent and
		// received bufs are the same and we know the channel is lossless.

		log.Debugf("HandshakeClient: Checking for lossiness")
		txbuf := []byte("\x1b[32mhello world\x1b[39m!\n")
		rxbuf := make([]byte, len(txbuf))

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

		var n int
		log.Debugf("HandshakeClient: Reading response")
		n, err = io.ReadFull(conn, rxbuf)
		if err != nil {
			log.Error(err)
			return err
		}

		if n != len(rxbuf) {
			return fmt.Errorf("packet size mismatch (expected %d, received %d)", len(rxbuf), n)
		}

		if bytes.Compare(rxbuf, txbuf) != 0 {
			return fmt.Errorf("HandshakeClient: lossiness check FAILED")
		}

		// Tell the server we're good.
		if _, err = conn.Write([]byte{flagAck}); err != nil {
			return err
		}

		log.Infof("HandshakeClient: lossiness check PASSED")
	}

	log.Debug("HandshakeClient: Connection established.")
	return nil
}
Example #28
0
// HandshakeServer establishes connection with the client making sure
// they both are in sync.
func HandshakeServer(conn io.ReadWriter) error {
	if tracing {
		defer trace.End(trace.Begin(""))
	}

	buf1byte := make([]byte, 1)
	syncBuf := make([]byte, 4096)

	if _, err := rand.Read(buf1byte); err != nil {
		log.Errorf("HandshakeClient: Could not read a random byte due to: %v", err)
	}
	pos := incrementByte(buf1byte[0])

	log.Debug("HandshakeServer: Waiting for incoming syn request...")

	// Sync packet is 2 bytes, however if we read more than 2
	// it means buffer is not empty and data is not trusted for this sync.

	n, err := io.ReadAtLeast(conn, syncBuf, 2)
	if err != nil {
		return err
	}
	if n != 2 {
		log.Debugf("HandshakeServer: Received %d bytes while awaiting for syn.", n)
	}
	syncBuf = syncBuf[n-2:]

	if syncBuf[0] != flagSyn {
		conn.Write([]byte{flagNak})
		return &HandshakeError{
			msg: fmt.Sprintf("Unexpected syn packet: %x", syncBuf[0]),
		}
	}

	log.Debugf("HandshakeServer: Received Syn. Writing SynAck.")

	// syncBuf[1] contains position token that needs to be incremented
	// by one to send it back.
	conn.Write([]byte{flagAck, incrementByte(syncBuf[1]), pos})
	pos = incrementByte(pos)

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

	ackType := buf1byte[0]
	if ackType != flagAck && ackType != flagDebugAck {
		conn.Write([]byte{flagNak})
		return &HandshakeError{
			msg: fmt.Sprintf("Not an ack packet received: %x", ackType),
		}
	}

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

	if buf1byte[0] != pos {
		conn.Write([]byte{flagNak})
		return &HandshakeError{
			msg: fmt.Sprintf(
				"HandshakeServer: Unexpected position %x, expected: %x",
				buf1byte[0], pos),
		}
	}

	if ackType == flagDebugAck {
		log.Debugf("HandshakeServer: Debug ACK received")
		rxbuf := make([]byte, 23)
		log.Debugf("HandshakeServer: Checking for lossiness")

		n, err := io.ReadFull(conn, rxbuf)
		if err != nil {
			return err
		}

		if n != len(rxbuf) {
			return fmt.Errorf("packet size mismatch (expected %d, received %d)", len(rxbuf), n)
		}

		// echo the data back
		_, err = conn.Write(rxbuf)
		if err != nil {
			return err
		}

		// wait for the ack
		if _, err = conn.Read(buf1byte); err != nil {
			return err
		}

		if buf1byte[0] != flagAck {
			return fmt.Errorf("lossiness check FAILED")
		}
		log.Infof("HandshakeServer: lossiness check PASSED")
	}

	log.Debug("HandshakeServer: Connection established.")
	return nil
}
Example #29
0
func ModemSend(c io.ReadWriter, data []byte, filename string) error {
	oBuffer := make([]byte, 1)

	// Wait for Poll
	if _, err := c.Read(oBuffer); err != nil {
		return err
	}

	// Send zero block with filename and size
	if oBuffer[0] == POLL {
		var send bytes.Buffer
		send.WriteString(filename)
		send.WriteByte(0x0)
		send.WriteString(fmt.Sprintf("%d", len(data)))
		for send.Len() < LONG_PACKET_PAYLOAD_LEN {
			send.Write([]byte{0x0})
		}

		sendBlock(c, 0, send.Bytes())

		// Wait for ACK
		if _, err := c.Read(oBuffer); err != nil {
			return err
		}

		if oBuffer[0] != ACK {
			return errors.New("Failed to send header block")
		}
	}

	// Wait for Poll
	if _, err := c.Read(oBuffer); err != nil {
		return err
	}

	// Send remaining data
	if oBuffer[0] == POLL {
		var blocks uint8 = uint8(len(data) / LONG_PACKET_PAYLOAD_LEN)
		if len(data) > int(int(blocks)*int(LONG_PACKET_PAYLOAD_LEN)) {
			blocks++
		}

		failed := 0
		var currentBlock uint8 = 0
		for currentBlock < blocks && failed < 10 {
			if int(int(currentBlock+1)*int(LONG_PACKET_PAYLOAD_LEN)) > len(data) {
				sendBlock(c, currentBlock+1, data[int(currentBlock)*int(LONG_PACKET_PAYLOAD_LEN):])
			} else {
				sendBlock(c, currentBlock+1, data[int(currentBlock)*int(LONG_PACKET_PAYLOAD_LEN):(int(currentBlock)+1)*int(LONG_PACKET_PAYLOAD_LEN)])
			}

			if _, err := c.Read(oBuffer); err != nil {
				return err
			}

			if oBuffer[0] == ACK {
				currentBlock++
			} else {
				failed++
			}
		}
	}

	// Wait for NAK and send EOT
	if _, err := c.Write([]byte{EOT}); err != nil {
		return err
	}

	if _, err := c.Read(oBuffer); err != nil {
		return err
	}

	if oBuffer[0] != NAK {
		return errors.New("")
	}

	// Send EOT again
	if _, err := c.Write([]byte{EOT}); err != nil {
		return err
	}

	if _, err := c.Read(oBuffer); err != nil {
		return err
	}

	if oBuffer[0] != ACK {
		return errors.New("Failed to send end block")
	}

	// Wait for POLL
	if _, err := c.Read(oBuffer); err != nil {
		return err
	}

	if oBuffer[0] != POLL {
		return errors.New("Failed to send end block")
	}

	// Send empty block to signify end
	var zero bytes.Buffer
	for zero.Len() < LONG_PACKET_PAYLOAD_LEN {
		zero.Write([]byte{0x0})
	}

	sendBlock(c, 0, zero.Bytes())

	// Wait for ACK
	if _, err := c.Read(oBuffer); err != nil {
		return err
	}

	if oBuffer[0] != ACK {
		return errors.New("Failed to send end block")
	}

	return nil
}
Example #30
0
func ModemReceive(c io.ReadWriter) (string, []byte, error) {
	var data bytes.Buffer

	// Start Connection
	if _, err := c.Write([]byte{POLL}); err != nil {
		return "", nil, err
	}

	// Read file information
	pktData, err := receivePacket(c)
	if err != nil {
		return "", nil, err
	}

	filenameEnd := bytes.IndexByte(pktData, 0x0)
	filename := string(pktData[0:filenameEnd])

	var filesize int
	fmt.Sscanf(string(pktData[filenameEnd+1:]), "%d", &filesize)

	if _, err := c.Write([]byte{POLL}); err != nil {
		return "", nil, err
	}

	// Read Packets
	for {
		pktData, err := receivePacket(c)
		if err == InvalidPacket {
			continue
		}

		if err != nil {
			return "", nil, err
		}

		// End of Transmission
		if pktData == nil {
			break
		}

		data.Write(pktData)
	}

	// Send NAK to respond to EOT
	if _, err := c.Write([]byte{NAK}); err != nil {
		return "", nil, err
	}

	oBuffer := make([]byte, 1)
	if _, err := c.Read(oBuffer); err != nil {
		return "", nil, err
	}

	// Send ACK to respond to second EOT
	if oBuffer[0] != EOT {
		return "", nil, err
	}

	if _, err := c.Write([]byte{ACK}); err != nil {
		return "", nil, err
	}

	// Second POLL to get remaining file or close
	if _, err := c.Write([]byte{POLL}); err != nil {
		return "", nil, err
	}

	// Get remaining data ( for now assume one file )
	if _, err := receivePacket(c); err != nil {
		return "", nil, err
	}

	return filename, data.Bytes()[0:filesize], nil
}