Git Product home page Git Product logo

Comments (7)

hugoArregui avatar hugoArregui commented on August 20, 2024

I found something, a chunk is missing in the server side and since a chunk is missing the ssn of the stream is incosistent. AFAICT the chunk is sent from the client but the server never get's it,
the reseembly queue ssn is smallest that any chunk in the queue, so it never process any of his chunks.

I don't know if I'm making sense, this is what happen AFAICT:

  • client sends chunk 1,2,3,4,5.. n
  • server receives 1,2,3 5..n
  • the condition to increase the ressembly queue nextSSN is to receive the next ssn, but the next ssn at some point is 4
  • since the nextSSN never get's 4, it's stuck there, so for chunks >= 4 although it gets them, it cannot process them

from sctp.

hugoArregui avatar hugoArregui commented on August 20, 2024

building with -race seems to prevent the problem!

from sctp.

hugoArregui avatar hugoArregui commented on August 20, 2024

I saw this on the server side:

sctp DEBUG: 19:15:39.232315 association.go:748: [0xc0000a51e0] chunkInit received in state 'Closed'
sctp DEBUG: 19:15:39.232929 association.go:900: [0xc0000a51e0] COOKIE-ECHO received in state 'Closed'
sctp DEBUG: 19:15:39.232965 association.go:713: [0xc0000a51e0] state change: 'Closed' => 'Established'
sctp DEBUG: 19:15:39.234451 association.go:1061: [0xc0000a51e0] accepted a new stream (streamIdentifier: 22)

and the code indicates:

    if state != cookieWait {
        // RFC 4960
        // 5.2.3.  Unexpected INIT ACK
        //   If an INIT ACK is received by an endpoint in any state other than the
        //   COOKIE-WAIT state, the endpoint should discard the INIT ACK chunk.
        //   An unexpected INIT ACK usually indicates the processing of an old or
        //   duplicated INIT chunk.
        return nil
    }

Probably this prevents the client/server to sync on the stream parameters, furthermore I think this is also causing a missalign, I see how at some point the client sends a fwdTsn but the server has fwdTsn disabled

from sctp.

hugoArregui avatar hugoArregui commented on August 20, 2024

I was able to trace back the problem to this:

  • at some point the reassembly queue is full, but since the stream is ordered, if the first chunk is missing the queue won't be readable.
  • The queue is not readable, so it cannot process new chunks
  • The queue doesn't get new chunks because is full so it won't ever be readeable again.

I was able to hack my way around the problem by changing the association handle data in this way:

	canPush := a.payloadQueue.canPush(d, a.peerLastTSN)
	if canPush {
		s := a.getOrCreateStream(d.streamIdentifier)
		if s == nil {
			// silentely discard the data. (sender will retry on T3-rtx timeout)
			// see pion/sctp#30
			a.log.Debugf("discard %d", d.streamSequenceNumber)
			return nil
		}

		if a.getMyReceiverWindowCredit() > 0 {
			// Pass the new chunk to stream level as soon as it arrives
			a.payloadQueue.push(d, a.peerLastTSN)
			s.handleData(d)
		} else if !d.unordered &&
			len(s.reassemblyQueue.unordered) == 0 {
			a.log.Debugf("[%s] buffer full, but reassemblyQueue is missing a chunk tsn=%d ssn=%d", a.name, d.tsn,d.streamSequenceNumber)
				a.payloadQueue.push(d, a.peerLastTSN)
				s.handleData(d)
		} else {
			a.log.Debugf("[%s] receive buffer full. dropping DATA with tsn=%d ssn=%d", a.name, d.tsn,d.streamSequenceNumber)
		}
	}

There may be an underline problem but I need to read the spec again to remind myself about the dialog between peer when it comes to buffer size and such.

from sctp.

enobufs avatar enobufs commented on August 20, 2024

PR #66 fixes a problem with ordered delivery, but my additional vnet test indicated, the buffer full lock-up happens with the unordered stream as well.

Modified fix incoming!

from sctp.

hugoArregui avatar hugoArregui commented on August 20, 2024

How can this happen with unordered delivery if the queue will always be readable if there is some unordered chunk there?

from sctp.

enobufs avatar enobufs commented on August 20, 2024

Say, you are sending two messages, A, and then B. With unordered, it could be received, B then A when unordered is true. (B is readable before A)

When both of the messages are 40KB, for instance, then B won't be fit in the 64-KB receiver buffer unless A is read by the app. If A has a missing chunk, this would be a dead-lock with the earlier code also.

from sctp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.