func (h serverHandler) serveRaft(w http.ResponseWriter, r *http.Request) { if !allowMethod(w, r.Method, "POST") { return } b, err := ioutil.ReadAll(r.Body) if err != nil { log.Println("etcdhttp: error reading raft message:", err) http.Error(w, "error reading raft message", http.StatusBadRequest) return } var m raftpb.Message if err := m.Unmarshal(b); err != nil { log.Println("etcdhttp: error unmarshaling raft message:", err) http.Error(w, "error unmarshaling raft message", http.StatusBadRequest) return } log.Printf("etcdhttp: raft recv message from %#x: %+v", m.From, m) if err := h.server.Process(context.TODO(), m); err != nil { log.Println("etcdhttp: error processing raft message:", err) writeError(w, err) return } w.WriteHeader(http.StatusNoContent) }
func (w *grpcWorker) RaftMessage(ctx context.Context, query *Payload) (*Payload, error) { if ctx.Err() != nil { return &Payload{}, ctx.Err() } for idx := 0; idx < len(query.Data); { sz := int(binary.LittleEndian.Uint32(query.Data[idx : idx+4])) idx += 4 msg := raftpb.Message{} if idx+sz-1 > len(query.Data) { return &Payload{}, x.Errorf( "Invalid query. Size specified: %v. Size of array: %v\n", sz, len(query.Data)) } if err := msg.Unmarshal(query.Data[idx : idx+sz]); err != nil { x.Check(err) } if msg.Type != raftpb.MsgHeartbeat && msg.Type != raftpb.MsgHeartbeatResp { fmt.Printf("RECEIVED: %v %v-->%v\n", msg.Type, msg.From, msg.To) } if err := w.applyMessage(ctx, msg); err != nil { return &Payload{}, err } idx += sz } // fmt.Printf("Got %d messages\n", count) return &Payload{}, nil }
func (h *pipelineHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { w.Header().Set("Allow", "POST") http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) return } w.Header().Set("X-Etcd-Cluster-ID", h.cid.String()) if err := checkClusterCompatibilityFromHeader(r.Header, h.cid); err != nil { http.Error(w, err.Error(), http.StatusPreconditionFailed) return } if from, err := types.IDFromString(r.Header.Get("X-Server-From")); err != nil { if urls := r.Header.Get("X-PeerURLs"); urls != "" { h.tr.AddRemote(from, strings.Split(urls, ",")) } } // Limit the data size that could be read from the request body, which ensures that read from // connection will not time out accidentally due to possible blocking in underlying implementation. limitedr := pioutil.NewLimitedBufferReader(r.Body, connReadLimitByte) b, err := ioutil.ReadAll(limitedr) if err != nil { plog.Errorf("failed to read raft message (%v)", err) http.Error(w, "error reading raft message", http.StatusBadRequest) recvFailures.WithLabelValues(r.RemoteAddr).Inc() return } var m raftpb.Message if err := m.Unmarshal(b); err != nil { plog.Errorf("failed to unmarshal raft message (%v)", err) http.Error(w, "error unmarshaling raft message", http.StatusBadRequest) recvFailures.WithLabelValues(r.RemoteAddr).Inc() return } receivedBytes.WithLabelValues(types.ID(m.From).String()).Add(float64(len(b))) if err := h.r.Process(context.TODO(), m); err != nil { switch v := err.(type) { case writerToResponse: v.WriteTo(w) default: plog.Warningf("failed to process raft message (%v)", err) http.Error(w, "error processing raft message", http.StatusInternalServerError) w.(http.Flusher).Flush() // disconnect the http stream panic(err) } return } // Write StatusNoContent header after the message has been processed by // raft, which facilitates the client to report MsgSnap status. w.WriteHeader(http.StatusNoContent) }
// Handles incoming requests. func (t *TCPServer) handleRequest(conn net.Conn) { var b []byte buffer := bytes.NewBuffer(b) bufReader := bufio.NewReader(conn) size := make([]byte, 4) ack := []byte{byte(AckMessageType)} for { typ, err := bufReader.ReadByte() if err != nil { log.Printf("Failed to read message type from TCP client") break } switch UserMessageType(typ) { case RaftMessageType: log.Printf("Received Raft message type") // Read size n, err := bufReader.Read(size) if err != nil || n != 4 { log.Printf("Failed to read message size from TCP client") break } byteCount, _ := xbinary.LittleEndian.Uint32(size, 0) if n, err := buffer.ReadFrom(io.LimitReader(bufReader, int64(byteCount))); err != nil || n != int64(byteCount) { log.Printf("Failed to read message from TCP client") break } m := raftpb.Message{} if err := m.Unmarshal(buffer.Bytes()); err != nil { log.Printf("Failed to decode message from TCP client") break } log.Printf("Applying Raft message") t.raft.Step(m) // Write the message in the connection channel. conn.Write(ack) // Reset Buffer buffer.Reset() default: break } } // Close the connection when you're done with it. conn.Close() }
func (dec *messageDecoder) decode() (raftpb.Message, error) { var m raftpb.Message var l uint64 if err := binary.Read(dec.r, binary.BigEndian, &l); err != nil { return m, err } buf := make([]byte, int(l)) if _, err := io.ReadFull(dec.r, buf); err != nil { return m, err } return m, m.Unmarshal(buf) }
func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { w.Header().Set("Allow", "POST") http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) return } if err := checkVersionCompability(r.Header.Get("X-Server-From"), serverVersion(r.Header), minClusterVersion(r.Header)); err != nil { plog.Errorf("request received was ignored (%v)", err) http.Error(w, errIncompatibleVersion.Error(), http.StatusPreconditionFailed) return } wcid := h.cid.String() w.Header().Set("X-Etcd-Cluster-ID", wcid) gcid := r.Header.Get("X-Etcd-Cluster-ID") if gcid != wcid { plog.Errorf("request received was ignored (cluster ID mismatch got %s want %s)", gcid, wcid) http.Error(w, errClusterIDMismatch.Error(), http.StatusPreconditionFailed) return } // Limit the data size that could be read from the request body, which ensures that read from // connection will not time out accidentally due to possible block in underlying implementation. limitedr := pioutil.NewLimitedBufferReader(r.Body, ConnReadLimitByte) b, err := ioutil.ReadAll(limitedr) if err != nil { plog.Errorf("failed to read raft message (%v)", err) http.Error(w, "error reading raft message", http.StatusBadRequest) return } var m raftpb.Message if err := m.Unmarshal(b); err != nil { plog.Errorf("failed to unmarshal raft message (%v)", err) http.Error(w, "error unmarshaling raft message", http.StatusBadRequest) return } if err := h.r.Process(context.TODO(), m); err != nil { switch v := err.(type) { case writerToResponse: v.WriteTo(w) default: plog.Warningf("failed to process raft message (%v)", err) http.Error(w, "error processing raft message", http.StatusInternalServerError) } return } // Write StatusNoContet header after the message has been processed by // raft, which faciliates the client to report MsgSnap status. w.WriteHeader(http.StatusNoContent) }
func (h Handler) serveRaft(ctx context.Context, w http.ResponseWriter, r *http.Request) { b, err := ioutil.ReadAll(r.Body) if err != nil { log.Println("etcdhttp: error reading raft message:", err) } var m raftpb.Message if err := m.Unmarshal(b); err != nil { log.Println("etcdhttp: error unmarshaling raft message:", err) } log.Printf("etcdhttp: raft recv message from %#x: %+v", m.From, m) if err := h.Server.Node.Step(ctx, m); err != nil { log.Println("etcdhttp: error stepping raft messages:", err) } }
func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { w.Header().Set("Allow", "POST") http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) return } wcid := h.cid.String() w.Header().Set("X-Etcd-Cluster-ID", wcid) gcid := r.Header.Get("X-Etcd-Cluster-ID") if gcid != wcid { log.Printf("rafthttp: request ignored due to cluster ID mismatch got %s want %s", gcid, wcid) http.Error(w, "clusterID mismatch", http.StatusPreconditionFailed) return } // Limit the data size that could be read from the request body, which ensures that read from // connection will not time out accidentally due to possible block in underlying implementation. limitedr := ioutils.NewLimitedBufferReader(r.Body, ConnReadLimitByte) b, err := ioutil.ReadAll(limitedr) if err != nil { log.Println("rafthttp: error reading raft message:", err) http.Error(w, "error reading raft message", http.StatusBadRequest) return } var m raftpb.Message if err := m.Unmarshal(b); err != nil { log.Println("rafthttp: error unmarshaling raft message:", err) http.Error(w, "error unmarshaling raft message", http.StatusBadRequest) return } if err := h.p.Process(context.TODO(), m); err != nil { switch v := err.(type) { case writerToResponse: v.WriteTo(w) default: log.Printf("rafthttp: error processing raft message: %v", err) http.Error(w, "error processing raft message", http.StatusInternalServerError) } return } w.WriteHeader(http.StatusNoContent) }
func (t *tcpTransport) handleConnection(c net.Conn) { for { p, e := ReadPacket(c) if e != nil { fmt.Fprintf(os.Stdout, "read from connection err:%s\n", e.Error()) } m := pb.Message{} if e := m.Unmarshal(p.Data); e != nil { fmt.Fprint(os.Stdout, "unmarshal protobuf Message data error:", e) } select { case t.reciv <- m: fmt.Fprintln(os.Stdout, "receive from:", m.From, "to:", m.To) default: } } }
func (h *raftHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if !allowMethod(w, r.Method, "POST") { return } wcid := strconv.FormatUint(h.clusterInfo.ID(), 16) w.Header().Set("X-Etcd-Cluster-ID", wcid) gcid := r.Header.Get("X-Etcd-Cluster-ID") if gcid != wcid { log.Printf("etcdhttp: request ignored due to cluster ID mismatch got %s want %s", gcid, wcid) http.Error(w, "clusterID mismatch", http.StatusPreconditionFailed) return } b, err := ioutil.ReadAll(r.Body) if err != nil { log.Println("etcdhttp: error reading raft message:", err) http.Error(w, "error reading raft message", http.StatusBadRequest) return } var m raftpb.Message if err := m.Unmarshal(b); err != nil { log.Println("etcdhttp: error unmarshaling raft message:", err) http.Error(w, "error unmarshaling raft message", http.StatusBadRequest) return } if err := h.server.Process(context.TODO(), m); err != nil { log.Println("etcdhttp: error processing raft message:", err) switch err { case etcdserver.ErrRemoved: http.Error(w, "cannot process message from removed node", http.StatusForbidden) default: writeError(w, err) } return } if m.Type == raftpb.MsgApp { h.stats.UpdateRecvApp(m.From, r.ContentLength) } w.WriteHeader(http.StatusNoContent) }
func (rn *raftNetwork) send(m raftpb.Message) { rn.mu.Lock() to := rn.recvQueues[m.To] if rn.disconnected[m.To] { to = nil } drop := rn.dropmap[conn{m.From, m.To}] dl := rn.delaymap[conn{m.From, m.To}] rn.mu.Unlock() if to == nil { return } if drop != 0 && rand.Float64() < drop { return } // TODO: shall we dl without blocking the send call? if dl.d != 0 && rand.Float64() < dl.rate { rd := rand.Int63n(int64(dl.d)) time.Sleep(time.Duration(rd)) } // use marshal/unmarshal to copy message to avoid data race. b, err := m.Marshal() if err != nil { panic(err) } var cm raftpb.Message err = cm.Unmarshal(b) if err != nil { panic(err) } select { case to <- cm: default: // drop messages when the receiver queue is full. } }
func (t *packetTransport) recvLoop() { defer t.logger.Printf("packet transport: recv loop exit") const maxRecvLen = 8192 b := make([]byte, maxRecvLen) for { n, remote, err := t.conn.ReadFrom(b) if err != nil { t.logger.Printf("packet transport: recv: %v (aborting)", err) return } else if n >= cap(b) { t.logger.Printf("packet transport: recv from %s: short read, %d >= %d (continuing)", remote, n, cap(b)) continue } var msg raftpb.Message if err := msg.Unmarshal(b[:n]); err != nil { t.logger.Printf("packet transport: recv from %s (sz %d): %v (%s) (continuing)", remote, n, err, b[:n]) continue } //t.logger.Printf("packet transport: recv from %s (sz %d/%d) OK", remote, n, msg.Size()) t.incomingc <- msg } }