code: func update(tcp header.TCP, inbound, outbound *stream, firstFin **stream) Result {
  	// Ignore segments out of the window.
  	s := seqnum.Value(tcp.SequenceNumber())
  	if !inbound.acceptable(s, dataLen(tcp)) {
  		return ResultAlive
  	}
  
  	flags := tcp.Flags()
  	if flags&header.TCPFlagRst != 0 {
  		inbound.rstSeen = true
  		return ResultReset
  	}
  
  	// Ignore segments that don't have the ACK flag, and those with the SYN
  	// flag.
  	if flags&header.TCPFlagAck == 0 || flags&header.TCPFlagSyn != 0 {
  		return ResultAlive
  	}
  
  	// Ignore segments that acknowledge not yet sent data.
  	ack := seqnum.Value(tcp.AckNumber())
  	if outbound.nxt.LessThan(ack) {
  		return ResultAlive
  	}
  
  	// Advance the "una" and "end" indices of the outbound stream.
  	if outbound.una.LessThan(ack) {
  		outbound.una = ack
  	}
  
  	if end := ack.Add(seqnum.Size(tcp.WindowSize())); outbound.end.LessThan(end) {
  		outbound.end = end
  	}
  
  	// Advance the "nxt" index of the inbound stream.
  	end := s.Add(logicalLen(tcp))
  	if inbound.nxt.LessThan(end) {
  		inbound.nxt = end
  	}
  
  	// Note the index of the FIN segment. And stash away a pointer to the
  	// first stream to see a FIN.
  	if flags&header.TCPFlagFin != 0 && !inbound.finSeen {
  		inbound.finSeen = true
  		inbound.fin = end - 1
  
  		if *firstFin == nil {
  			*firstFin = inbound
  		}
  	}
  
  	return ResultAlive
  }
docs: // update updates the state of inbound and outbound streams, given the supplied
  // inbound segment. For outbound segments, this same function can be called with
  // swapped inbound/outbound streams.