func (t *Table) writeData(buf *bufio.Writer) (int, error) { firstrow := true if t.dataget != nil { for { ok, data := t.dataget() if !ok { break } if (!firstrow) && t.CloseEachColumn { if _, err := t.writeRecordHorBorder(buf); err != nil { return -1, err } } firstrow = false if _, err := t.writeRecord(data, buf); err != nil { return -1, err } } } else if t.CountData() != 0 { for ii, data := range t.Data { if _, err := t.writeRecord(data, buf); err != nil { return -1, err } if t.CloseEachColumn { if ii < len(t.Data)-1 { if _, err := t.writeRecordHorBorder(buf); err != nil { return -1, err } } } } } return buf.Buffered(), buf.Flush() }
func (t *Table) writeBottomBorder(buf *bufio.Writer) (int, error) { if _, err := buf.WriteString(Borders[t.border][BKLeftBottom]); err != nil { return 0, err } if err := t.writeBorderTopButtomData(buf, BKHorizontalBorder, BKBottomToTop, BKRightBottom); err != nil { return 0, err } return buf.Buffered(), buf.Flush() }
func writeNodeName(key string, writer *bufio.Writer) { if writer.Buffered() > 0 { writer.WriteByte('\n') } writer.WriteByte('[') writer.WriteString(key) writer.WriteByte(']') writer.WriteByte('\n') }
func encodePacket(writer *bufio.Writer, sequence uint16, payload []byte) (int, error) { var length int if len(payload) > MTU { return 0, fmt.Errorf("payload cannot be greater than %d bytes", MTU) } h := new(PacketHeader) h.Length = uint16(len(payload) + binary.Size(h)) h.Sequence = sequence err := binary.Write(writer, binary.BigEndian, h) if err == nil { _, err = writer.Write(payload) } if err == nil { length = writer.Buffered() err = writer.Flush() } return length, err }
func (t *Table) writeHeader(buf *bufio.Writer) (int, error) { if t.caption != "" { buf.WriteString(t.caption) buf.WriteString(eol.EOL) } buf.WriteString(Borders[t.border][BKLeftTop]) cntCols := t.columnsvisible.Len() for num, c := range t.columnsvisible { cnw, _ := buf.WriteString(strings.Repeat(Borders[t.border][BKHorizontalBorder], t.getWidth(c))) if num < cntCols-1 { buf.WriteString(Borders[t.border][BKTopToBottom]) } else { buf.WriteString(Borders[t.border][BKRighttop]) if cnw > 0 { buf.WriteString(eol.EOL) } } } if t.VisibleHeader { buf.WriteString(Borders[t.border][BKVerticalBorder]) for num, c := range t.columnsvisible { caption := fmt.Sprintf(t.GetMaskFormat(c), c.Caption) buf.WriteString(trimEnds(caption, t.getWidth(c))) if num < cntCols-1 { buf.WriteString(Borders[t.border][BKVertical]) } else { buf.WriteString(Borders[t.border][BKVerticalBorder]) } } buf.WriteString(eol.EOL) buf.WriteString(Borders[t.border][BKLeftToRight]) if err := t.writeBorderTopButtomData(buf, BKHorizontal, BKBottomCross, BKRightToLeft); err != nil { return 0, err } } return buf.Buffered(), buf.Flush() }
func SHandshake(c net.Conn, br *bufio.Reader, bw *bufio.Writer, timeout time.Duration) (err error) { defer func() { if r := recover(); r != nil { err = r.(error) } }() // Read C0 // if timeout > 0 { // c.SetReadDeadline(time.Now().Add(timeout)) // } c0, err := br.ReadByte() CheckError(err, "SHandshake() Read C0") if c0 != 0x03 { return errors.New(fmt.Sprintf("SHandshake() Got C0: %x", c0)) } // Read C1 c1 := make([]byte, RTMP_SIG_SIZE) // if timeout > 0 { // c.SetReadDeadline(time.Now().Add(timeout)) // } _, err = io.ReadAtLeast(br, c1, RTMP_SIG_SIZE) CheckError(err, "SHandshake Read C1") logger.ModulePrintf(logHandler, log.LOG_LEVEL_DEBUG, "SHandshake() Flash player version is %d.%d.%d.%d", c1[4], c1[5], c1[6], c1[7]) fmt.Print("\n", hex.Dump(c1)) // Send S0+S1 err = bw.WriteByte(0x03) CheckError(err, "SHandshake() Send S0") s1 := CreateRandomBlock(RTMP_SIG_SIZE) // Set Timestamp // binary.BigEndian.PutUint32(s1, uint32(GetTimestamp())) binary.BigEndian.PutUint32(s1, uint32(0)) // Set FlashPlayer version for i := 0; i < 8; i++ { s1[i] = FMS_VERSION[i] } // if s1w, err := ioutil.ReadFile("/home/nimo/Downloads/s1.bin"); err == nil { // fmt.Println("Loading s1 from file, size:", len(s1w)) // copy(s1, s1w) // } fmt.Print("\n", hex.Dump(s1)) serverDigestOffset := ImprintWithDigest(s1, GENUINE_FMS_KEY[:36]) if serverDigestOffset == 0 { return errors.New("ImprintWithDigest failed") } _, err = bw.Write(s1) // CheckError(err, "SHandshake() Send S1") // if timeout > 0 { // c.SetWriteDeadline(time.Now().Add(timeout)) // } // err = bw.Flush() // CheckError(err, "SHandshake() Flush S0+S1") scheme := 0 clientDigestOffset := ValidateDigest(c1, 8, GENUINE_FP_KEY[:30]) if clientDigestOffset == 0 { clientDigestOffset = ValidateDigest(c1, 772, GENUINE_FP_KEY[:30]) if clientDigestOffset == 0 { //return errors.New("SHandshake C1 validating failed") scheme = 2 } else { scheme = 1 } } logger.ModulePrintf(logHandler, log.LOG_LEVEL_DEBUG, "SHandshake() scheme = %d", scheme) if scheme < 2 { digestResp, err := HMACsha256(c1[clientDigestOffset:clientDigestOffset+SHA256_DIGEST_LENGTH], GENUINE_FMS_KEY) CheckError(err, "SHandshake Generate digestResp") // Generate S2 s2 := CreateRandomBlock(RTMP_SIG_SIZE) signatureResp, err := HMACsha256(s2[:RTMP_SIG_SIZE-SHA256_DIGEST_LENGTH], digestResp) CheckError(err, "SHandshake Generate S2 HMACsha256 signatureResp") DumpBuffer("SHandshake signatureResp", signatureResp, 0) for index, b := range signatureResp { s2[RTMP_SIG_SIZE-SHA256_DIGEST_LENGTH+index] = b } // Send S2 _, err = bw.Write(s2) CheckError(err, "SHandshake() Send S2") } else { // Send S2 as C1 copy _, err = bw.Write(c1) CheckError(err, "SHandshake() Send S2") } // Send S2 // _, err = bw.Write(s2) // CheckError(err, "SHandshake() Send S2") // if timeout > 0 { // // c.SetWriteDeadline(time.Now().Add(timeout)) // } time.Sleep(time.Duration(300) * time.Millisecond) fmt.Println("flush s0+s1+s2", bw.Buffered()) err = bw.Flush() CheckError(err, "SHandshake() Flush S2") // Read C2 if timeout > 0 { // c.SetReadDeadline(time.Now().Add(timeout)) } c2 := make([]byte, RTMP_SIG_SIZE) //_, err = io.ReadAtLeast(br, c2, RTMP_SIG_SIZE) _, err = br.Read(c2) CheckError(err, "SHandshake() Read C2") // TODO: check C2 return }