func read(client *Client, conn *tls.Conn) { buffer := make([]byte, ERR_RESPONSE_LEN) if _, err := conn.Read(buffer); err != nil { log.Printf("read err %v, %v, %p\n", err, err == io.EOF, client) client.chConnectionErr <- conn return } errRsp := &errResponse{ Command: uint8(buffer[0]), Status: uint8(buffer[1]), } if err := binary.Read(bytes.NewBuffer(buffer[2:]), binary.BigEndian, &errRsp.Identifier); err != nil { log.Println("read identifier err", err) return } if errRsp.Command != ERR_RESPONSE_CMD { log.Println("unknown err response", buffer) return } errMsg, ok := ApplePushResponses[errRsp.Status] if !ok { log.Println("unknown err status", buffer) return } log.Printf("get err response : %##v, %s\n", errRsp, errMsg) client.chErrResponse <- errRsp }
func readConnection(conn *tls.Conn, readChannel chan []byte, errorChannel chan error) { for { data := make([]byte, 512) num, err := conn.Read(data) if err != nil { errorChannel <- err return } readChannel <- data[:num] } }
func ReadPacket(logger *log.Logger, conn *tls.Conn) (*Packet, error) { inbuf := make([]byte, 1024) br, err := conn.Read(inbuf) if err != nil { return nil, err } if br == 0 { return nil, errors.New("disconnected") } if br < 4 { return nil, errors.New("short read") } br = br - 4 phead := inbuf[0:4] b := bytes.NewReader(phead) var pilen uint32 err = binary.Read(b, binary.BigEndian, &pilen) plen := int(pilen) - 4 if err != nil { conn.Close() return nil, err } pdata := inbuf[4:] for { if br >= plen { break } buf := make([]byte, (plen - br)) nr, err := conn.Read(buf) if err != nil { conn.Close() return nil, err } if nr == 0 { return nil, err } pdata = append(pdata, buf...) br = br + nr } var p Packet err = json.Unmarshal(pdata[:plen], &p) if err != nil { return nil, err } return &p, nil }
func readError(conn *tls.Conn, quit chan<- int, c chan<- NotificationError) { p := make([]byte, 6, 6) for { n, err := conn.Read(p) e := NewNotificationError(p[:n], err) c <- e if err != nil { quit <- 1 return } } }
func readError(client_conn *tls.Conn, c chan NotificationError) { var readb []byte readb = make([]byte, 6, 6) n, _ := client_conn.Read(readb) if n > 0 { notificationerror := NotificationError{} notificationerror.Command = uint8(readb[0]) notificationerror.Status = uint8(readb[1]) notificationerror.Identifier = uint32(readb[2])<<24 + uint32(readb[3])<<16 + uint32(readb[4])<<8 + uint32(readb[5]) c <- notificationerror } }
func readError(conn *tls.Conn, quit chan<- uint32, c chan<- error) { p := make([]byte, 6, 6) for { n, err := conn.Read(p) e := NewNotificationError(p[:n], err) fmt.Errorf("Read error in APNS : " + e.Error()) if e.OtherError == nil { last_fail = e.Identifier } c <- e if err != nil { quit <- 1 return } } }
/** * 监听APNSSocket的返回结果,当有返回时,意味着发生错误了,这时把错误发到channel,同时关闭socket。 */ func monitorConn(conn *tls.Conn, app string, sandbox bool) { defer CapturePanic(fmt.Sprint("panic when monitor Connection %s", app)) defer conn.Close() reply := make([]byte, 6) n, err := conn.Read(reply) if err != nil && reply[0] != 8 { if strings.HasSuffix(err.Error(), "use of closed network connection") { log.Println("close the network connection") return } else { log.Printf("error when read from socket %s, %d", err, n) } } log.Printf("return %x, the id is %x", reply, reply[2:]) buf := bytes.NewBuffer(reply[2:]) var id int32 binary.Read(buf, binary.BigEndian, &id) rsp := &APNSRespone{reply[0], reply[1], id, conn, app, sandbox} responseCN <- rsp }
// GetValueFromContentsBlock returns the contents type in the header, as well as the contents contained within. func GetValueFromContentsBlock(tlsConn *tls.Conn) (contents_type string, contents string, n int, err error) { buf := make([]byte, 512) n, err = tlsConn.Read(buf) if err != nil { if err.Error() == "EOF" { return "", "", 0, nil } return "", "", 0, err } begin_message := string(buf[0:n]) if !(begin_message[:11] == "-----BEGIN " && begin_message[len(begin_message)-5:] == "-----") { error_text := fmt.Sprintf("The beginning string was invalid. It was %s", begin_message) return "", "", 0, errors.New(error_text) } contents_type = getContentsType(begin_message) end_message := getEndMessage(contents_type) contents = "" total_bytes := 0 for { n, err := tlsConn.Read(buf) if err != nil && err.Error() != "EOF" { return "", "", 0, err } message := string(buf[0:n]) if message == end_message { break } total_bytes += n contents += message } return contents_type, contents, total_bytes, nil }
func Publishv1(input chan []*FileEvent, registrar chan []*FileEvent, config *NetworkConfig) { var buffer bytes.Buffer var socket *tls.Conn var sequence uint32 var err error socket = connect(config) defer socket.Close() for events := range input { buffer.Truncate(0) compressor, _ := zlib.NewWriterLevel(&buffer, 3) for _, event := range events { sequence += 1 writeDataFrame(event, sequence, compressor) } compressor.Flush() compressor.Close() compressed_payload := buffer.Bytes() // Send buffer until we're successful... oops := func(err error) { // TODO(sissel): Track how frequently we timeout and reconnect. If we're // timing out too frequently, there's really no point in timing out since // basically everything is slow or down. We'll want to ratchet up the // timeout value slowly until things improve, then ratchet it down once // things seem healthy. log.Printf("Socket error, will reconnect: %s\n", err) time.Sleep(1 * time.Second) socket.Close() socket = connect(config) } SendPayload: for { // Abort if our whole request takes longer than the configured // network timeout. socket.SetDeadline(time.Now().Add(config.timeout)) // Set the window size to the length of this payload in events. _, err = socket.Write([]byte("1W")) if err != nil { oops(err) continue } binary.Write(socket, binary.BigEndian, uint32(len(events))) if err != nil { oops(err) continue } // Write compressed frame socket.Write([]byte("1C")) if err != nil { oops(err) continue } binary.Write(socket, binary.BigEndian, uint32(len(compressed_payload))) if err != nil { oops(err) continue } _, err = socket.Write(compressed_payload) if err != nil { oops(err) continue } // read ack response := make([]byte, 0, 6) ackbytes := 0 for ackbytes != 6 { n, err := socket.Read(response[len(response):cap(response)]) if err != nil { log.Printf("Read error looking for ack: %s\n", err) socket.Close() socket = connect(config) continue SendPayload // retry sending on new connection } else { ackbytes += n } } // TODO(sissel): verify ack // Success, stop trying to send the payload. break } // Tell the registrar that we've successfully sent these events registrar <- events } /* for each event payload */ } // Publish
func ReadDataEncrypted(tlsConn *tls.Conn, private_key []byte) (metadata FileMetadata, contents string, operation_int int, err error) { buf := make([]byte, 512) n, err := tlsConn.Read(buf) if err != nil { if err.Error() == "EOF" { return FileMetadata{}, "", EOF_CONST, nil } return FileMetadata{}, "", ERR_CONST, err } begin_message := string(buf[0:n]) if begin_message != getBeginMessage("DATA") { if begin_message == PING { return FileMetadata{}, "", PING_CONST, nil } error_text := fmt.Sprintf("The beginning DATA string was invalid. It was %s", begin_message) return FileMetadata{}, "", 0, errors.New(error_text) } n, err = tlsConn.Read(buf) if err != nil { if err.Error() == "EOF" { return FileMetadata{}, "", EOF_CONST, nil } return FileMetadata{}, "", ERR_CONST, err } begin_metadata_message := string(buf[0:n]) if begin_metadata_message != getBeginMessage("METADATA") { error_text := fmt.Sprintf("The beginning METADATA string was invalid. It was %s", begin_metadata_message) return FileMetadata{}, "", ERR_CONST, errors.New(error_text) } operation_type, operation, n, err := GetValueFromContentsBlock(tlsConn) checkErr(err, tlsConn) err = checkDataFormatting(operation_type, "OPERATION", n) checkErr(err, tlsConn) path_type, path, n, err := GetValueFromContentsBlock(tlsConn) checkErr(err, tlsConn) err = checkDataFormatting(path_type, "PATH", n) checkErr(err, tlsConn) size_type, size, n, err := GetValueFromContentsBlock(tlsConn) checkErr(err, tlsConn) err = checkDataFormatting(size_type, "SIZE", n) checkErr(err, tlsConn) is_dir_type, is_dir, n, err := GetValueFromContentsBlock(tlsConn) checkErr(err, tlsConn) err = checkDataFormatting(is_dir_type, "IS_DIR", n) checkErr(err, tlsConn) modification_time_type, modification_time, n, err := GetValueFromContentsBlock(tlsConn) checkErr(err, tlsConn) err = checkDataFormatting(modification_time_type, "MODIFICATION_TIME", n) checkErr(err, tlsConn) n, err = tlsConn.Read(buf) if err != nil { if err.Error() == "EOF" { return FileMetadata{}, "", EOF_CONST, nil } return FileMetadata{}, "", ERR_CONST, err } end_metadata_message := string(buf[0:n]) if end_metadata_message != getEndMessage("METADATA") { error_text := fmt.Sprintf("The ending string was invalid. It was %s", end_metadata_message) return FileMetadata{}, "", ERR_CONST, errors.New(error_text) } encrypted_contents_type, encrypted_contents, n, err := GetValueFromContentsBlock(tlsConn) checkErr(err, tlsConn) err = checkDataFormatting(encrypted_contents_type, "CONTENTS", n) checkErr(err, tlsConn) n, err = tlsConn.Read(buf) if err != nil { if err.Error() == "EOF" { return FileMetadata{}, "", EOF_CONST, nil } return FileMetadata{}, "", ERR_CONST, err } end_message := string(buf[0:n]) if end_message != getEndMessage("DATA") { error_text := fmt.Sprintf("The ending string was invalid. It was %s", end_message) return FileMetadata{}, "", ERR_CONST, errors.New(error_text) } var is_dir_bool bool if is_dir == "1" { is_dir_bool = true } else if is_dir == "0" { is_dir_bool = false } else { return FileMetadata{}, "", ERR_CONST, errors.New("The value for IS_DIR was not valid.") } modification_time_int64, err := strconv.ParseInt(modification_time, 10, 64) checkErr(err, tlsConn) size_int64, err := strconv.ParseInt(size, 10, 64) checkErr(err, tlsConn) operation_int, err = strconv.Atoi(operation) checkErr(err, tlsConn) var contents_byteslice []byte if (operation_int == FILE_DELETED_CONST) || (operation_int == FILE_ADDED_CONST && is_dir_bool) { contents_byteslice = []byte{} } else { contents_byteslice, err = GBClientAESEncryption.Decrypt(private_key, []byte(encrypted_contents)) checkErr(err, tlsConn) } metadata = FileMetadata{path, is_dir_bool, modification_time_int64, size_int64} return metadata, string(contents_byteslice), operation_int, nil }
// ReadData reads from the conn and returns the metadata, contents, and intended operation of the data, // according to the Gopherbox file transfer scheme. func ReadData(tlsConn *tls.Conn) (metadata GBServerDatabase.FileMetadata, contents string, operation_int int, err error) { buf := make([]byte, 512) n, err := tlsConn.Read(buf) if err != nil { if err.Error() == "EOF" { return GBServerDatabase.FileMetadata{}, "", EOF_CONST, nil } return GBServerDatabase.FileMetadata{}, "", ERR_CONST, err } begin_message := string(buf[0:n]) if begin_message != getBeginMessage("DATA") { if begin_message == PING { return GBServerDatabase.FileMetadata{}, "", PING_CONST, nil } error_text := fmt.Sprintf("The beginning DATA string was invalid. It was %s", begin_message) return GBServerDatabase.FileMetadata{}, "", 0, errors.New(error_text) } n, err = tlsConn.Read(buf) if err != nil { if err.Error() == "EOF" { return GBServerDatabase.FileMetadata{}, "", EOF_CONST, nil } return GBServerDatabase.FileMetadata{}, "", ERR_CONST, err } begin_metadata_message := string(buf[0:n]) if begin_metadata_message != getBeginMessage("METADATA") { error_text := fmt.Sprintf("The beginning METADATA string was invalid. It was %s", begin_metadata_message) return GBServerDatabase.FileMetadata{}, "", ERR_CONST, errors.New(error_text) } operation_type, operation, n, err := GetValueFromContentsBlock(tlsConn) checkErr(err, tlsConn) err = checkDataFormatting(operation_type, "OPERATION", n) checkErr(err, tlsConn) path_type, path, n, err := GetValueFromContentsBlock(tlsConn) checkErr(err, tlsConn) err = checkDataFormatting(path_type, "PATH", n) checkErr(err, tlsConn) size_type, size, n, err := GetValueFromContentsBlock(tlsConn) checkErr(err, tlsConn) err = checkDataFormatting(size_type, "SIZE", n) checkErr(err, tlsConn) is_dir_type, is_dir, n, err := GetValueFromContentsBlock(tlsConn) checkErr(err, tlsConn) err = checkDataFormatting(is_dir_type, "IS_DIR", n) checkErr(err, tlsConn) modification_time_type, modification_time, n, err := GetValueFromContentsBlock(tlsConn) checkErr(err, tlsConn) err = checkDataFormatting(modification_time_type, "MODIFICATION_TIME", n) checkErr(err, tlsConn) n, err = tlsConn.Read(buf) if err != nil { if err.Error() == "EOF" { return GBServerDatabase.FileMetadata{}, "", EOF_CONST, nil } return GBServerDatabase.FileMetadata{}, "", ERR_CONST, err } end_metadata_message := string(buf[0:n]) if end_metadata_message != getEndMessage("METADATA") { error_text := fmt.Sprintf("The ending string was invalid. It was %s", end_metadata_message) return GBServerDatabase.FileMetadata{}, "", ERR_CONST, errors.New(error_text) } contents_type, contents, n, err := GetValueFromContentsBlock(tlsConn) checkErr(err, tlsConn) err = checkDataFormatting(contents_type, "CONTENTS", n) checkErr(err, tlsConn) n, err = tlsConn.Read(buf) if err != nil { if err.Error() == "EOF" { return GBServerDatabase.FileMetadata{}, "", EOF_CONST, nil } return GBServerDatabase.FileMetadata{}, "", ERR_CONST, err } end_message := string(buf[0:n]) if end_message != getEndMessage("DATA") { error_text := fmt.Sprintf("The ending string was invalid. It was %s", end_message) return GBServerDatabase.FileMetadata{}, "", ERR_CONST, errors.New(error_text) } var is_dir_bool bool if is_dir == "1" { is_dir_bool = true } else if is_dir == "0" { is_dir_bool = false } else { return GBServerDatabase.FileMetadata{}, "", ERR_CONST, errors.New("The value for IS_DIR was not valid.") } modification_time_int64, err := strconv.ParseInt(modification_time, 10, 64) checkErr(err, tlsConn) size_int64, err := strconv.ParseInt(size, 10, 64) checkErr(err, tlsConn) operation_int, err = strconv.Atoi(operation) checkErr(err, tlsConn) metadata = GBServerDatabase.FileMetadata{path, is_dir_bool, modification_time_int64, size_int64} return metadata, contents, operation_int, nil }