Sending Mail in seaside+Gemstone " a Message: NotUnderstood occurred (error 2010), a UndefinedObject does not understand #'isEmpty' " - smalltalk

Tried with a similar question earlier, but could not I make headway. So I did new tests and here is the new question:
I did a brand new installation of PHARO 1.4 and GEMSTONE 3.0.1.2 on the same machine. (Linux CENTOS). Loaded seaside 3.0 in Pharo and version 3.0.7.1 in Gemstone using the latest version of Gemtools (1.0 beta 87) with the latest version of glass workspace (1.0 beta 8.7.4).
I opened the workspace and evaluated:
(WAEmailMessage
from: (WAEmailAddress address: 'xx#aa.com' username: 'fromMe')
to: (WAEmailAddress address: 'shyam#localhost' username: 'shyam')
subject: 'Email Test')
body: 'This is a Test Email sent';
send.
(BTW, As the default mail host in Gemstone is "mailhost", I added the following line to the /etc/hosts file127.0.0.1 localhost mailhost ).
On Pharo the message is sent and received correctly, while in Gemstone I get
a MessageNotUnderstood occurred (error 2010), a UndefinedObject does not understand #'isEmpty', in the method
readSmtpResult
| result firstChar |
[self readWillNotBlockWithin: 5000]
whileFalse: [GsFile stderr log: 'Waiting for server to write...'].
result := self readString: 500.
result isEmpty =========================> HERE result is "nil".
ifTrue:
[self log: 'Empty result'.
^false].
The reason being that result returns a nil.
I tried with similar results also on MAC OS X which instead went into a loop in the lines above.
Using tcpdump -X -i lo tcp port 25 and WireShark, I noticed that for GEMSTONE, I saw NO activity while the packets were correctly exchanged for PHARO.
Evidently, I am doing something terribly wrong to get it wrong on two different systems.
Any idea ?
Thanks
Shyam.

result is nil because #readString: returned nil.
It seems that the peer does not send any data. As you already traced that there is no activity on port 25 going on, are you sure that the SMTP parameters are correct?
Seaside-Email contains code that you can use to configure your SMTP-Server.
Given you have your Seaside application seasideApp, you can do the following:
seasideApp configuration
addParent: WAEmailConfiguration instance.
seasideApp
preferenceAt: #smtpServer put: 'your.smtp.host';
preferenceAt: #smtpPort put: 25;
preferenceAt: #smtpUsername put: 'your.smtp.username.or.nil.if.unecessary';
preferenceAt: #smtpUsername put: 'your.smtp.password.or.nil.if.unecessary';
yourself.
Note that #smtpServer and smtpPort must be configured the way described, as they are used in the GemStone version of GRPlatform>>#seasideDeliverEmailMessage:. I opted to deliberately not use the GemStone defaults.
Also, setting the SMTP parameters this way is ment to work cross-platform; if it does not, please contact me directly.

Related

While Download Works But Post Request Not (Chilkat)

I am facing a very wired issue, and passed so many hours to find the issue but without any luck :(
i have setup a web server on my mobile (android)..
and trying to use that using my vb application
where i simple call Download method on the very sample url (same ip/port), it works and save the response body as downloaded file.
but when i try to send post command it is not working, it gives error "Connection rejected"
here is the code to download:
objDHTTP.Download("http://192.168.1.101:8000/fileAdmin.php", strAppDir & "\wtf-response.txt")
here is the code when i tried to use same url and port for post request:
objDRequest.Path = "/fileAdmin.php"
objDRequest.AddParam("fileAction", "Upload")
objDRequest.AddParam("fileName", "DB.sql")
objDRequest.AddFileForUpload("adminFile", strAppDir & "\c.dll")
objDResponse = objDHTTP.SynchronousRequest(strServerIP, 8000, False, objDRequest)
but it does not works and throws above error
here is the success response (for download method):
<ChilkatLog>
<Download>
<DllDate>Dec 21 2018</DllDate>
<ChilkatVersion>9.5.0.76</ChilkatVersion>
<Architecture>Little Endian; 32-bit</Architecture>
<Language>.NET 4.0</Language>
<VerboseLogging>0</VerboseLogging>
<url>http://192.168.1.101:8000/fileAdmin.php</url>
<toLocalPath>G:\wtf-sucess.txt</toLocalPath>
<currentWorkingDir>G:\</currentWorkingDir>
<a_httpDownload>
<httpDownloadFile>
<localFilePath>G:\wtf-sucess.txt</localFilePath>
<localFileAlreadyExists>1</localFileAlreadyExists>
<quickHttpRequest>
<httpVerb>GET</httpVerb>
<url>http://192.168.1.101:8000/fileAdmin.php</url>
<openHttpConnection>
<info>Opening connection directly to HTTP server.</info>
<httpHostname>192.168.1.101</httpHostname>
<httpPort>8000</httpPort>
<tls>False</tls>
<info>HTTP connection succeeded.</info>
</openHttpConnection>
<buildQuickRequest>
<genStartLine>
<startLine>GET /fileAdmin.php HTTP/1.1</startLine>
</genStartLine>
<addCookies>
<info>Not auto-adding cookies.</info>
<sendCookies>1</sendCookies>
<cookieDir></cookieDir>
</addCookies>
</buildQuickRequest>
<sendRequestHeader>
<sendHeaderElapsedMs>0</sendHeaderElapsedMs>
</sendRequestHeader>
<statusCode>200</statusCode>
<statusText>OK</statusText>
<checkCloseConnection>
<info>Response includes connection:close header (or proxy-connection:close header)</info>
</checkCloseConnection>
</quickHttpRequest>
<outputLocalFileSize>26</outputLocalFileSize>
<numOutputBytesWritten>26</numOutputBytesWritten>
</httpDownloadFile>
</a_httpDownload>
<totalElapsedMs>47</totalElapsedMs>
<ContentLength>0</ContentLength>
<info>Success.</info>
</Download>
</ChilkatLog>
And here is the error/fail response (for post request):
<ChilkatLog>
<SynchronousRequest>
<DllDate>Dec 21 2018</DllDate>
<ChilkatVersion>9.5.0.76</ChilkatVersion>
<Architecture>Little Endian; 32-bit</Architecture>
<Language>.NET 4.0</Language>
<VerboseLogging>0</VerboseLogging>
<domain>191.168.1.101</domain>
<port>8000</port>
<ssl>0</ssl>
<httpRequest>
<httpVersion>1.1</httpVersion>
<verb>POST</verb>
<path>/fileAdmin.php</path>
<contentType>multipart/form-data</contentType>
<charset>windows-1252</charset>
<sendCharset>0</sendCharset>
<mimeHeader></mimeHeader>
<requestParams>
<requestItem>
<name>fileAction</name>
<value>Upload</value>
</requestItem>
<requestItem>
<name>fileName</name>
<value>DB.sql</value>
</requestItem>
<requestItem>
<name>adminFile</name>
<fileOnDisk>G:\c.dll</fileOnDisk>
<numValueBytes>8697</numValueBytes>
</requestItem>
</requestParams>
</httpRequest>
<fullRequest>
<a_synchronousRequest>
<generateRequestHeader>
<httpRequestGenStartLine>
<genStartLine>
<startLine>POST /fileAdmin.php HTTP/1.1</startLine>
</genStartLine>
</httpRequestGenStartLine>
<addCookies>
<info>Not auto-adding cookies.</info>
<sendCookies>1</sendCookies>
<cookieDir></cookieDir>
</addCookies>
<genMultipartFormData>
<requestParam>
<name>fileAction</name>
</requestParam>
<requestParam>
<name>fileName</name>
</requestParam>
<requestParam>
<name>adminFile</name>
<filename>G:\c.dll</filename>
</requestParam>
</genMultipartFormData>
</generateRequestHeader>
<fullHttpRequest>
<domain>191.168.1.101</domain>
<port>8000</port>
<ssl>0</ssl>
<openHttpConnection>
<info>Opening connection directly to HTTP server.</info>
<httpHostname>191.168.1.101</httpHostname>
<httpPort>8000</httpPort>
<tls>False</tls>
<socket2Connect>
<connect2>
<connectSocket>
<connect_ipv6_or_ipv4>
<info>Connection attempt failed.</info>
<maxWaitTimeMs>10000</maxWaitTimeMs>
<totalMsWaitedSoFar>2100</totalMsWaitedSoFar>
</connect_ipv6_or_ipv4>
<connect_ipv6_or_ipv4>
<info>Connection attempt failed.</info>
<maxWaitTimeMs>10000</maxWaitTimeMs>
<totalMsWaitedSoFar>2150</totalMsWaitedSoFar>
</connect_ipv6_or_ipv4>
</connectSocket>
<ConnectFailReason>Connection rejected</ConnectFailReason>
<error>A few possible causes for a connection being rejected are:</error>
<error>- A firewall (software or hardware), such as Windows Firewall, is blocking the connection .</error>
<error>- Nothing is listening at the remote host:port</error>
</connect2>
</socket2Connect>
</openHttpConnection>
</fullHttpRequest>
<success>0</success>
</a_synchronousRequest>
<success>0</success>
</fullRequest>
<totalTime>Elapsed time: 4390 millisec</totalTime>
<error>Failed.</error>
</SynchronousRequest>
</ChilkatLog>
can any one tell me what could be the reason for this?
thanks in advance
best regards
The likely reasons are present in the LastErrorText:
<ConnectFailReason>Connection rejected</ConnectFailReason>
<error>A few possible causes for a connection being rejected are:</error>
<error>- A firewall (software or hardware), such as Windows Firewall, is blocking the connection .</error>
<error>- Nothing is listening at the remote host:port</error>
My guess is that the Windows Firewall is blocking the outbound POST.
This example shows the errors one would get for various TCP socket connection problems: https://www.example-code.com/vbnet/socket_connect_fail.asp

OrientDB serverside NullPointerException while serializing record using binary protocol

I've just started to implement binary protocol API to orientDB with C++. Current Version of used orientDB is "orientdb-community-2.2.29" with win 10 x64 and java 1.8. Since I've tried to query "select * from XXXX" on example DB serverside exceptions are thrown and no record is serialized to client. Here are the logs after successful connection and query:
2017-12-03 14:14:12:561 INFO {db=Site} /0:0:0:0:0:0:0:1:2520 - Writing bytes (4+0=4 bytes): null [OChannelBinaryServer]$ANSI{green {db=Site}} Error on unmarshalling record #73:0 (java.lang.NullPointerException)
java.lang.NullPointerException
at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.getRecordBytes(ONetworkProtocolBinary.java:2894)
at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.writeRecord(ONetworkProtocolBinary.java:2907)
at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.writeIdentifiable(ONetworkProtocolBinary.java:2697)
at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.serializeValue(ONetworkProtocolBinary.java:1639)
at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.command(ONetworkProtocolBinary.java:1584)
at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.executeRequest(ONetworkProtocolBinary.java:660)
at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.sessionRequest(ONetworkProtocolBinary.java:394)
at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.execute(ONetworkProtocolBinary.java:217)
at com.orientechnologies.common.thread.OSoftThread.run(OSoftThread.java:81)
2017-12-03 14:14:12:561 WARNI {db=Site} Cannot serialize record: XXXX#73:0{Name:[2],IDs:[1]} v3 [ONetworkProtocolBinary]
Before writing the "null" bytes the recordID, position and record version is serialized and received on client side correctly, also querying from Studio or console works like a charm. I've tried to change the class - property to STRING or EMBEDDEDMAP with the same problem.
Thanks in advance for help :-)
Fortunately I found the mistake at my own: wrong SerializationImpl was configured. The correct configuration must be ORecordSerializerBinary and not ONetworkProtocolBinary.

Setting a timeout on webservice consumer built with org.apache.axis.client.Call and running on Domino

I'm maintaining an antedeluvian Notes application which connects to a SAP back-end via a manually done 'Webservice'
The server is running Domino Release 7.0.4FP2 HF97.
The Webservice is not the more recently Webservice Consumer, but a large Java agent which is using Apache soap.jar (org.apache.soap). Below an example of the calling code.
private Call setupSOAPCall() {
Call call = new Call();
SOAPHTTPConnection conn = new SOAPHTTPConnection();
call.setSOAPTransport(conn);
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
There has been a change in the SAP system which is now taking 8 minutes to complete (verified by SAP Team).
I'm getting an error message as follows:
[SOAPException: faultCode=SOAP-ENV:Client; msg=For input string: "906 "; targetException=java.lang.NumberFormatException: For input string: "906 "]
I found a blog article describing the error message quite closely:
https://thejavablog.wordpress.com/category/jmeter/
and I've come to the hypothesis that it is a timeout message that is returning to my Call object and that this timeout message is being incorrectly parsed, hence the NumberFormat Exception.
Looking at my logs I can see that there is a time difference of 62 seconds between my call and the response.
I recommended that the server setting in the server document, tab Internet Protocols/HTTP/Timeouts/Request timeouts be changed from 60 seconds to 600 seconds, and the http task restarted with
tell http restart
I've re-run the tests and I am getting the same error, and the time difference is still slightly more than 60 seconds, which is not what I was expecting.
I read Michael Rulnau's blog entry
http://www.mruhnau.net/2014/06/how-to-overcome-domino-webservice.html
which points to this APR
http://www-01.ibm.com/support/docview.wss?uid=swg1LO48272
but I'm not convinced that this would apply in this case, since there is no way that IBM would know that my Java agent is in fact making a Soap call.
My current hypothesis is that I have to use either the setTimeout() method on
org.apache.axis.client.Call
https://axis.apache.org/axis/java/apiDocs/org/apache/axis/client/Call.html
or on the org.apache.soap.transport.http.SOAPHTTPConnection
https://docs.oracle.com/cd/B13789_01/appdev.101/b12024/org/apache/soap/transport/http/SOAPHTTPConnection.html
and that the timeout value is an apache default, not something that is controlled by the Domino server.
I'd be grateful for any help.
I understand your approach, and I hope this is the correct one to solve your problem.
Add a debug (console write would be fine) that display the default Timeout then try to increase it to 10 min.
SOAPHTTPConnection conn = new SOAPHTTPConnection();
System.out.println("time out is :" + conn.getTimeout());
conn.setTimeout(600000);//10 min in ms
System.out.println("after setting it, time out is :" + conn.getTimeout());
call.setSOAPTransport(conn);
Now keep in mind that Dommino has also a Max LotusScript/Java execution time, check this value and (at least for a try) change it: http://www.ibm.com/support/knowledgecenter/SSKTMJ_9.0.1/admin/othr_servertasksagentmanagertab_r.html (it's version 9 help but this part should be identical)
I've since discovered that it wasn't my code generating the error; the default timeout for the apache axis SOAPHTTPConnetion is 0, i.e. no timeout.

Boost ASIO and UDP Errors

I've got two test programs (A & B)that are nearly identical, that use the same boost asio UDP async code.
Here is the receive call:
_mSocket.async_receive_from(
boost::asio::buffer(_mRecvBuffer), _mReceiveEndpoint,
boost::bind(&UdpConnection::handle_receive, this,_mReceiveEndpoint,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
// _mReceiveEndpoint is known and good. the buffer is good too.
// here's the handler
void handle_receive(const udp::endpoint recvFromEP, const boost::system::error_code& error,std::size_t bytesRecv/*bytes_transferred*/)
{
boost::shared_ptr<std::string> message(new std::string(_mRecvBuffer.c_array(),bytesRecv));
if (!error)
{
doSomeThingGood();
}
else {
cerr << "UDP Recv error : " << error << endl;
}
}
So here's what happens, all on localhost.
If I start program 'A' first, then program 'B', 'A' gives a UDP Recv error : server:10061.
Program 'A' continues to send just fine and 'B' receives just fine.
You can swap 'A' and 'B' in the above sentence and it is still true.
IF I attempt a reset of the bad read condition by calling mSocket.async_receive_from again, I get error 10054.
I've looked these errors up on the web..... not very helpful.
Anybody have any ideas as to what these mean, and how I can recover inside the program if this condition occurs? Is there a way to reset the socket?
Sanity check.... can both programs operate on loopback with only two ports?
A send = 20000, A receive = 20001
B send = 20001, B receive = 20000
TL;DR
It appears as though if I try to listen before I'm sending, I get an error & I can't recover from it. If I listen after sending, I'm fine.
-- EDIT - It appears that McAfee host intrusion prevention is doing something nasty to me.... If I debug in VS2010, I get stuck in their DLL.
Thanks
In my receive handler, I wasn't calling _mSocket.async_receive_from() again.... I just printed the error and exited.
Silly mistake, just posting here in case it helps anyone else.
Also for a similar problem with a different resolution:
_mSocket.set_option(boost::asio::socket_base::reuse_address(true));
helps if you have multiple listeners.
Several sources explain that you should use SO_REUSEADDR on windows. But none mention that it is possible to receive UDP message with and without binding the socket.
The code below binds the socket to a local listen_endpoint, that is essential, because without that you can and will still receive your UDP messages, but by default your will have exclusive ownership of the port.
However if you set reuse_address(true) on the socket (or on the acceptor when using TCP), and bind the socket afterwards, it will enable multiple applications, or multiple instances of your own application to do it again, and everyone will receive all messages.
// Create the socket so that multiple may be bound to the same address.
boost::asio::ip::udp::endpoint listen_endpoint(
listen_address, multicast_port);
// == important part ==
socket_.open(listen_endpoint.protocol());
socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
socket_.bind(listen_endpoint);
// == important part ==
boost::array<char, 2000> recvBuffer;
socket_.async_receive_from(boost::asio::buffer(recvBuffer), m_remote_endpoint,
boost::bind(&SocketReader::ReceiveUDPMessage, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)
source:
http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/multicast/receiver.cpp

Troubleshooting WebRTC code

I'm pulling my hair out with this one. A month or so ago, I was able to put together a proof-of-concept WebRTC demo, using some sample code from the good folks at SignalR. The demo is located here, the source for it is here, and it does what it's supposed to do.
But when I took that code and moved it into our actual application, I haven't been able to get it to work. Of course the code had to be changed significantly - different backends, different set of frameworks and supporting code, supporting multiple simultaneous connections, that sort of thing - but the core logic is very similar. But I can't get it to work.
I've put together a sample app here that demonstrates the problem:
https://bitbucket.org/smithkl42/signalr.webrtc
The core WebRTC logic is all in this TypeScript file:
https://bitbucket.org/smithkl42/signalr.webrtc/src/tip/SignalR.WebRTC/Scripts/Media/WebRTC.ts?at=default
It's several hundred lines long, so I won't bother posting it here, but you can see it by clicking on the link above.
When it runs, it produces output like this:
12:17:58.531 WebRTCController.call(): Calling 7d9e0d39-5047-4afe-86e5-e6e01b9f5955 when preparations have finished
12:17:58.533 WebRTCController.prepareForCall(): Preparing for call: localSessionId='39d2df53-6854-415a-8748-b5230eda2eb1'; remoteSessionId='7d9e0d39-5047-4afe-86e5-e6e01b9f5955'
12:18:0.139 Object.(): The user has granted media device access, so proceeding to prepare for call
12:18:0.141 Connection.createPeerConnection(): Creating peer connection; using stunServer stun:stun1.l.google.com:19302
12:18:0.144 (): Preparations finished. Creating and sending JSEP offer. Util.js:21
12:18:0.272 Connection.handleIceCandidate(): STUN server has found an ICE candidate (event.type='icecandidate').
12:18:0.282 Connection.handleIceCandidate(): STUN server has found an ICE candidate (event.type='icecandidate').
(More like that)
12:18:0.655 WebRTCController.handleJsepAnswer(): Handling JsepAnswer from 7d9e0d39-5047-4afe-86e5-e6e01b9f5955
12:18:0.694 Object.(): Sending ICE candidate to the remote machine: {"sdpMLineIndex":0,"sdpMid":"audio","candidate":"a=candidate:2999745851 1 udp 2113937151 192.168.56.1 62978 typ host generation 0\r\n"}
12:18:0.706 Object.(): Sending ICE candidate to the remote machine: {"sdpMLineIndex":0,"sdpMid":"audio","candidate":"a=candidate:2999745851 2 udp 2113937151 192.168.56.1 62978 typ host generation 0\r\n"}
(More like that)
But then it never connects, i.e., the video from the other side never starts playing. At the signaling layer, I can tell by the logs and by stepping through the code that the first browser is sending a JSEP offer; the second browser is receiving it, storing it and sending back an appropriate JSEP answer; and the first machine is storing that answer. Each peerConnection is then finding the ICE candidates and sending them to the remote machine; and each peerConnection is receiving and apparently trying those ICE candidates; and the peerConnections are even raising the onaddstream event. But the video never starts playing.
The state of the peerConnection object all the way through looks like this:
(iceGatheringState=new; iceState=starting; readyState=active)
The frustrating bit is that every so often, maybe one time out of 20, it does work, i.e., both videos show up. So I'm not doing everything wrong. It sounds like a timing issue of some sort - but I can't figure out what it is. And so far as I can tell, there's not much in the WebRTC objects (specifically RTCPeerConnection) to tell you what's going wrong.
I hate to ask anybody else to do my troubleshooting for me, but... well, I'm running out of options. Does anybody else see anything I'm doing obviously wrong?
Update 2012-12-19: I'm making some progress. I realized I was calling peerConnection.setLocalDescription() synchronously, i.e., without specifying callbacks. So now I've got some lines of code that look like this:
// Answer the call by sending a JsepAnswer message.
connection.peerConnection.createAnswer(
answer => {
connection.peerConnection.setLocalDescription(answer, () => {
var signalState: mData.SignalState = {
FromSessionId: connection.localSessionId,
ToSessionId: connection.remoteSessionId,
Message: JSON.stringify(answer)
};
me.roomHub.server.jsepAnswer(signalState);
mUtil.log("Sent JSEP answer: " + signalState.Message);
connection.readyForIceCandidates.resolve();
},
error => {
mUtil.error("Error setting local description from created answer: " + error + "; answer=" + JSON.stringify(answer));
});
},
error => {
mUtil.error("Error creating answer: " + error);
}, me.mediaConstraints);
And the setLocalDescription() error callback is showing this error:
16:14:42.439 WebRTCController.handleJsepOffer(): Error setting local description from created answer: SetLocalDescription failed.; answer={"sdp":"v=0\r\no=- 439659381 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE audio video\r\na=msid-semantic: WMS u9fhVrWeLLweqb5ubLkw61Ijsh6BM6vZLhjf\r\nm=audio 1 RTP/SAVPF 103 104 111 0 8 107 106 105 13 126\r\nc=IN IP4 0.0.0.0\r\na=rtcp:1 IN IP4 0.0.0.0\r\na=ice-ufrag:vOKflTJ56gV0R9i0\r\na=ice-pwd:9nuXPMDvQ2mZATFCQyEzPRQz\r\na=sendrecv\r\na=mid:audio\r\na=rtcp-mux\r\na=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:m9q9pmLgLuFnfFC09KXKW5p8TjsKk+VdqX0OWv77\r\na=rtpmap:103 ISAC/16000\r\na=rtpmap:104 ISAC/32000\r\na=rtpmap:111 opus/48000/2\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:107 CN/48000\r\na=rtpmap:106 CN/32000\r\na=rtpmap:105 CN/16000\r\na=rtpmap:13 CN/8000\r\na=rtpmap:126 telephone-event/8000\r\na=ssrc:548068416 cname:IXg8QRisWrd7+7f8\r\na=ssrc:548068416 msid:u9fhVrWeLLweqb5ubLkw61Ijsh6BM6vZLhjf a0\r\na=ssrc:548068416 mslabel:u9fhVrWeLLweqb5ubLkw61Ijsh6BM6vZLhjf\r\na=ssrc:548068416 label:u9fhVrWeLLweqb5ubLkw61Ijsh6BM6vZLhjfa0\r\nm=video 1 RTP/SAVPF 100 116 117\r\nc=IN IP4 0.0.0.0\r\na=rtcp:1 IN IP4 0.0.0.0\r\na=ice-ufrag:vOKflTJ56gV0R9i0\r\na=ice-pwd:9nuXPMDvQ2mZATFCQyEzPRQz\r\na=sendrecv\r\na=mid:video\r\na=rtcp-mux\r\na=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:m9q9pmLgLuFnfFC09KXKW5p8TjsKk+VdqX0OWv77\r\na=rtpmap:100 VP8/90000\r\na=rtpmap:116 red/90000\r\na=rtpmap:117 ulpfec/90000\r\na=ssrc:1460425980 cname:IXg8QRisWrd7+7f8\r\na=ssrc:1460425980 msid:u9fhVrWeLLweqb5ubLkw61Ijsh6BM6vZLhjf v0\r\na=ssrc:1460425980 mslabel:u9fhVrWeLLweqb5ubLkw61Ijsh6BM6vZLhjf\r\na=ssrc:1460425980 label:u9fhVrWeLLweqb5ubLkw61Ijsh6BM6vZLhjfv0\r\n","type":"answer"}
Now I just need to figure out why that particular SDP - which comes straight from the createAnswer() method - is failing.
Update 2012-12-20: I've created an online demonstration of the problem here: http://srdemo.alanta.com/. I've also turned on Chrome debug logging, with the result that I see a bunch of errors that look like this:
[6584:7308:1220/091356:ERROR:rtc_peer_connection_handler.cc(84)] Native session description is null.
[6584:7308:1220/091356:ERROR:rtc_peer_connection_handler.cc(84)] Native session description is null.
[6584:7308:1220/091356:ERROR:rtc_peer_connection_handler.cc(84)] Native session description is null.
[6584:7308:1220/091356:ERROR:rtc_peer_connection_handler.cc(84)] Native session description is null.
[6584:7308:1220/091356:ERROR:rtc_peer_connection_handler.cc(84)] Native session description is null.
Not sure what relationship they have to my problem, but I'm continuing to look into it.
*Edit 2012-12-20: I've managed (I think) to narrow the problem down. See this question for more precise details.
Figured it out. Turns out that SignalR 1.0 RC1 has a bug in it that changes any "+" in a string into a space. So lines in the SDP that looked like this:
a=ice-pwd:qZFVvgfnSso1b8UV1SUDd2+z
Were getting changed into this:
a=ice-pwd:qZFVvgfnSso1b8UV1SUDd2 z
But because not every SDP had a "+" in it on a critical line, sometimes it would work. Everything explained.
The bug has been reported to the good folks working on SignalR (see https://github.com/SignalR/SignalR/issues/1194), and in the meantime, a simple encodeURIComponent() and decodeURIComponent() around the strings in question fixed it.