MCPcopy
hub / github.com/grafana/dskit / writeTo

Method writeTo

kv/memberlist/tcp_transport.go:514–589  ·  view source on GitHub ↗
(b []byte, addr string)

Source from the content-addressed store, hash-verified

512}
513
514func (t *TCPTransport) writeTo(b []byte, addr string) error {
515 // Open connection, write packet header and data, data hash, close. Simple.
516 c, err := t.getConnection(addr, t.cfg.PacketDialTimeout)
517 if err != nil {
518 return err
519 }
520
521 closed := false
522 defer func() {
523 if !closed {
524 // If we still need to close, then there was another error. Ignore this one.
525 _ = c.Close()
526 }
527 }()
528
529 // Compute the digest *before* setting the deadline on the connection (so that the time
530 // it takes to compute the digest is not taken in account).
531 // We use md5 as quick and relatively short hash, not in cryptographic context.
532 // It's also used to detect if the whole packet has been received on the receiver side.
533 digest := md5.Sum(b)
534
535 // Prepare the header *before* setting the deadline on the connection.
536 headerBuf := bytes.Buffer{}
537 headerBuf.WriteByte(byte(packet))
538
539 // We need to send our address to the other side, otherwise other side can only see IP and port from TCP header.
540 // But that doesn't match our node address (new TCP connection has new random port), which confuses memberlist.
541 // So we send our advertised address, so that memberlist on the receiving side can match it with correct node.
542 // This seems to be important for node probes (pings) done by memberlist.
543 ourAddr := t.getAdvertisedAddr()
544 if len(ourAddr) > 255 {
545 return fmt.Errorf("local address too long")
546 }
547
548 headerBuf.WriteByte(byte(len(ourAddr)))
549 headerBuf.WriteString(ourAddr)
550
551 if t.cfg.PacketWriteTimeout > 0 {
552 deadline := time.Now().Add(t.cfg.PacketWriteTimeout)
553 err := c.SetDeadline(deadline)
554 if err != nil {
555 return fmt.Errorf("setting deadline: %v", err)
556 }
557 }
558
559 _, err = c.Write(headerBuf.Bytes())
560 if err != nil {
561 return fmt.Errorf("sending local address: %v", err)
562 }
563
564 n, err := c.Write(b)
565 if err != nil {
566 return fmt.Errorf("sending data: %v", err)
567 }
568 if n != len(b) {
569 return fmt.Errorf("sending data: short write")
570 }
571

Callers 1

writeWorkerMethod · 0.95

Calls 9

getConnectionMethod · 0.95
getAdvertisedAddrMethod · 0.95
debugLogMethod · 0.95
ErrorfMethod · 0.80
SetDeadlineMethod · 0.80
CloseMethod · 0.65
AddMethod · 0.65
WriteMethod · 0.45
LogMethod · 0.45

Tested by

no test coverage detected