There is a race condition in Transmitter.java when
using asynchronous mode. The problem arises as follows:
1) Thread 1 (main thread) instantiates the Session
object in asynchronous mode, which starts up the
Receiver thread. Thread 1 then continues sending
submit_sm using Session.submit()
2) Thread 2 (the Receiver object) is now reading back
from the connection and calling the user's
ServerPDUEventListener. In some cases, however, the
Receiver may detect an error and sends Generic NACK
using Transmitter, or the user callback needs to send
another message (i.e. deliver_sm_resp) using the same
Session/Transmitter object.
There is no mechanism to protect Receiver and the main
thread from both attempting to call Transmitter.send at
the exact same time, causing an interleaving of code
writing to the BufferedOutputStream wrapped around
Socket.getOutputStream(), which as I understand is NOT
thread-safe.
Also, this allows for interleaved calls to
PDU.assignSequenceNumber(), which could result in two
PDUs getting the SAME sequence number, which will cause
very unpredictable errors.
The solution is in Transmitter.java:
public synchronized void send(PDU pdu)
throws ValueNotSetException,
IOException
Add the "synchronized" keyword to the send method to
prevent two threads from interleaved access. This
protects access to the sequence generation and to the
network output stream.
Logged In: YES
user_id=1108378
Originator: NO
TCPIPConnection: it may be that the OutputStream returned by Socket.getOutputStream() is not threadsafe, but the BufferedOutputStream that it is wrapped in is thread safe, and all access happens via the buffered stream, so there doesn't appear to be a problem.
The unsafe incrementing of the sequence number in PDU was separately resolved in Tracker item 1614488.
Paolo