<?xml version="1.0" encoding="iso-8859-1"?><!-- generator="b2evolution/1.10.3" -->
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title>Olivier Langlois's blog</title>
						<link>http://blog.olivierlanglois.net/index.php</link>
				<description>Olivier Langlois's blog: I am sharing tips about programming as I find them</description>
				<language>en-CA</language>
				<docs>http://backend.userland.com/rss</docs>
				<admin:generatorAgent rdf:resource="http://b2evolution.net/?v=1.10.3"/>
				<ttl>60</ttl>
								<item>
					<title>Linksys Wireless-N Gaming Router WRT330N model review</title>
					<link>http://blog.olivierlanglois.net/index.php/2010/12/05/linksys_wireless_n_gaming_router_wrt330n</link>
					<pubDate>Mon, 06 Dec 2010 04:53:03 +0000</pubDate>
					<dc:creator>lano1106</dc:creator>
					<category domain="main">TCP/IP</category>
<category domain="alt">Video games</category>					<guid isPermaLink="false">169@http://blog.olivierlanglois.net/</guid>
					<description>It is an ok Gigabit router with its wireless functionality working fine. However when connecting a PS3 on the router and let it test the router capabilities, the router fails the UPnP testing. In my opinion, this is inexcusable when you sell a product at premium price and you market it as a "gaming" router, you would expect the company to have tested it with all the mainstream consoles.


I have contacted Cisco/Linksys customer support chat service to report the problem and get assistance and basically, I have been told something like that the problem was my fault and that I had to change some obscure and unrelated WiFi settings to fix my problem.

I was not satisfied by the answer and I decided to see for myself why the PS3 is reporting a UPnP failure with that router.

2 tools have been required for the analysis.


  Wireshark
  An Ethernet hub


A hub is a piece of networking hardware allowing you to share an Ethernet link between more than 2 network devices. Those were common in the 90s when processing power and memory were expensive. Today they have been replaced by the more robust and powerful Ethernet switches. My setup has been to plug my PC between the Linksys router and my PS3 and let Wireshark running on my PC sniff the UPnP exchange between them.

Before going in the details of the PS3 UPnP test, I want to share some interesting details about the whole PS3 Internet testing which is close to be undocumented on the Internet

Testing Internet Connection:

It does it by doing a HTTP request on fus01.ps3.update.playstation.net.


GET /update/ps3/list/us/ps3-updatelist.txt HTTP/1.1
Host: fus01.ps3.update.playstation.net
Connection: Keep-Alive
Accept-Encoding: identity
User-Agent: PS3Update-agent/1.0.0 libhttp/1.0.0

HTTP/1.1 200 OK
Server: Apache
ETag: "4d8c4dbf774c6349ad778577e53bd8c7:1285037260"
Last-Modified: Tue, 21 Sep 2010 02:47:40 GMT
Accept-Ranges: bytes
Content-Length: 252
Content-Type: text/plain
Date: Mon, 06 Dec 2010 03:22:33 GMT
Connection: keep-alive

# US
Dest=84;CompatibleSystemSoftwareVersion=3.5000-;
Dest=84;ImageVersion=0000b437;SystemSoftwareVersion=3.5000;CDN=http://dus01.ps3.update.playstation.net/update/ps3/image/us/2010_0921_0215e26d1dadeb950471a9c3397a140a/PS3UPDAT.PUP;CDN_Timeout=30;


Test PSN connection:

It does so by establishing an HTTPS connection with auth.np.ac.playstation.net. Obviously since it is encrypted, I cannot comment much about it.

NAT Type testing.

The PS3 sends a series of STUN (Session Traversal Utilities for NAT) (I am mentionning STUN in another blog entry for the curious) requests to us.np.stun.playstation.net

So now, lets get back to the UPnP testing. Here is a short overview of the whole procedure:


  Broadcast a request to find all network devices that are a InternetGatewayDevice
  Query its capability by requesting a XML file
  If the service WANIPConnection is supported, continue the test
  Call GetExternalIPAddress to obtain the router public Internet IP address
  Call AddPortMapping to open a public port on which all inbound traffic will be forwarded to the PS3


Here is how goes the exchange with the WRT330N router:


PS3 Broadcast:

M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 5
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1

2 seconds timeout. Retransmit the same request

After about 1.5 seconds after the 2nd retransmission, the router finally reply:

HTTP/1.1 200 OK
EXT:
SERVER: ipOS/7.2, UPnP/1.0, ipSSDPDevice/1.0
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1
LOCATION: http://192.168.1.1/root.sxml
CACHE-CONTROL: max-age=1800
USN: uuid:1C7AE0B4-AF9D-3FD9-AC27-04FAE3357DD5::urn:schemas-upnp-org:device:InternetGatewayDevice:1
Content-Length: 0

PS3 request this:

GET /root.sxml HTTP/1.1
HOST: 192.168.1.1:80

PS3 UPnP request:

POST /wipconn HTTP/1.1
HOST: 192.168.1.1:4444
Content-Length: 290
Content-Type: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress"

&#60;s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&#62;
   &#60;s:Body&#62;
      &#60;u:GetExternalIPAddress xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"&#62;
      &#60;/u:GetExternalIPAddress&#62;
   &#60;/s:Body&#62;
&#60;/s:Envelope&#62;

Linksys Router:

HTTP/1.1 200 OK
SERVER: ipOS/6.8 UPnP/1.0 IGD/1.0
EXT: 
Transfer-Encoding: Chunked

197
&#60;?xml version="1.0" encoding="UTF-8" standalone="yes"?>&#60;soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&#62;&#60;soap:Body&#62;&#60;u:GetExternalIPAddressResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"&#62;&#60;NewExternalIPAddress&#62;xxx.xxx.xxx.xxx&#60;/NewExternalIPAddress&#62;&#60;/u:GetExternalIPAddressResponse&#62;&#60;/soap:Body&#62;&#60;/soap:Envelope&#62;
0

2nd PS3 UPnP request:

POST /wipconn HTTP/1.1
HOST: 192.168.1.1:4444
Content-Length: 644
Content-Type: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"

&#60;s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&#62;
   &#60;s:Body&#62;
      &#60;u:AddPortMapping xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"&#62;
 &#60;NewRemoteHost&#62;&#60;/NewRemoteHost&#62;
 &#60;NewExternalPort&#62;3658&#60;/NewExternalPort&#62;
 &#60;NewProtocol&#62;UDP&#60;/NewProtocol&#62;
 &#60;NewInternalPort&#62;3658&#60;/NewInternalPort&#62;
 &#60;NewInternalClient&#62;192.168.1.109&#60;/NewInternalClient&#62;
 &#60;NewEnabled&#62;1&#60;/NewEnabled&#62;
 &#60;NewPortMappingDescription&#62;192.168.1.109:3658 to 3658 (UDP)&#60;/NewPortMappingDescription&#62;
 &#60;NewLeaseDuration&#62;0&#60;/NewLeaseDuration&#62;
      &#60;/u:AddPortMapping&#62;
   &#60;/s:Body&#62;
&#60;/s:Envelope&#62;

Linksys Router:

HTTP/1.1 200 OK
SERVER: ipOS/6.8 UPnP/1.0 IGD/1.0
EXT: 
Transfer-Encoding: Chunked
151
&#60;?xml version="1.0" encoding="UTF-8" standalone="yes"?>&#60;soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&#62;&#60;soap:Body>&#60;u:AddPortMappingResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"&#62;&#60;/u:AddPortMappingResponse&#62;&#60;/soap:Body>&#60;/soap:Envelope&#62;
0


By looking the exchange it looks all good and in the router log, there is even an entry that shows that the Port mapping occured:


[INFO] Sun Dec 05 20:40:09 2010 UPnP renew entry 255.255.255.255 &#60;-&#62; 24.37.208.168:3658 &#60;-&#62; 192.168.1.109:3658 UDP timeout:-1 '192.168.1.109:3658 to 3658 (UDP)'


I initially believed that the error is the returned length of the router reply for the AddPortMapping request. It reports a length of 151 bytes but if you count them, I come to something around 340 chars! The GetExternalIPAddress call has the same problem. The reported size is 197 while in fact, I count around 410 chars!

However, a coworker of mine pointed out to me that the chunk size values are in hex as described in the RFC 2616. So I can only conclude that the problem comes from the PS3 that does not handle correctly HTTP chunked transfer coding in the context of UPnP exchange.

Another indication that the chunked transfer encoding in the replies is the culprit of the problem, it is that at the end of both exchange between the PS3 and the WRT330N is that the PS3 is sending back TCP RST segments to the router which means that the PS3 is closing its connection with the router before the router having finished to send its replies.

For your reference, here is an exchange with my new NetGear router, the WNDR37AV that works like a charm!


In less than 2 ms the reply to the M-SEARCH query comes back.

HTTP/1.1 200 OK
Cache-Control: max-age=1800
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1
USN: uuid:12345678-0000-0000-0000-00000000abcd::urn:schemas-upnp-org:device:InternetGatewayDevice:1
EXT:
Server: Linux/2.6.15-1.2054_FC5 UPnP/1.0 miniupnpd/1.0
Location: http://192.168.1.1:5555/rootDesc.xml

PS3 request this:

GET /rootDesc.xml HTTP/1.1
HOST: 192.168.1.1:5555

PS3 UPnP request:

POST /ctl/IPConn HTTP/1.1
HOST: 192.168.1.1:5555
Content-Length: 290
Content-Type: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress"

&#60;s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&#62;
   &#60;s:Body&#62;
      &#60;u:GetExternalIPAddress xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"&#62;
      &#60;/u:GetExternalIPAddress&#62;
   &#60;/s:Body&#62;
&#60;/s:Envelope&#62;

Netgear reply:

HTTP/1.1 200 OK
Content-Type: text/xml; charset="utf-8"
Connection: close
Content-Length: 356
Server: Linux/2.6.15-1.2054_FC5 UPnP/1.0 miniupnpd/1.0
Ext:

&#60;?xml version="1.0"?&#62;
&#60;s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&#62;&#60;s:Body&#62;&#60;u:GetExternalIPAddressResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"&#62;&#60;NewExternalIPAddress&#62;xxx.xxx.xxx.xxx&#60;/NewExternalIPAddress&#62;&#60;/u:GetExternalIPAddressResponse&#62;&#60;/s:Body&#62;&#60;/s:Envelope&#62;

2nd PS3 UPnP request:
POST /ctl/IPConn HTTP/1.1
HOST: 192.168.1.1:5555
Content-Length: 644
Content-Type: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"

&#60;s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&#62;
   &#60;s:Body&#62;
      &#60;u:AddPortMapping xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"&#62;
 &#60;NewRemoteHost&#62;&#60;/NewRemoteHost&#62;
 &#60;NewExternalPort&#62;3658&#60;/NewExternalPort&#62;
 &#60;NewProtocol&#62;UDP&#60;/NewProtocol&#62;
 &#60;NewInternalPort&#62;3658&#60;/NewInternalPort&#62;
 &#60;NewInternalClient&#62;192.168.1.109&#60;/NewInternalClient&#62;
 &#60;NewEnabled&#62;1&#60;/NewEnabled&#62;
 &#60;NewPortMappingDescription&#62;192.168.1.109:3658 to 3658 (UDP)&#60;/NewPortMappingDescription&#62;
 &#60;NewLeaseDuration&#62;0&#60;/NewLeaseDuration&#62;
      &#60;/u:AddPortMapping&#62;
   &#60;/s:Body&#62;
&#60;/s:Envelope&#62;

Netgear reply:

HTTP/1.1 200 OK
Content-Type: text/xml; charset="utf-8"
Connection: close
Content-Length: 260
Server: Linux/2.6.15-1.2054_FC5 UPnP/1.0 miniupnpd/1.0
Ext:

&#60;?xml version="1.0"?&#62;
&#60;s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&#62;&#60;s:Body&#62;&#60;u:AddPortMappingResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"/&#62;
&#60;/s:Body&#62;
&#60;/s:Envelope&#62;


In conclusion, I am disapointed by the quality of the Linksys product and the lack of attention of details that the company did put in the QA before the release of that product since the UPnP bug could have been caught by a very simple test in less than 5 minutes. Apparently the bug is in the PS3 that does not support UPnP interaction with HTTP replies using chunked transfer coding but I was expecting to purchase a router compatible with my PS3 when I bought a gaming router. For that reason, I prefer the NetGear router.

Happy networking!</description>
					<content:encoded><![CDATA[<p>It is an ok Gigabit router with its wireless functionality working fine. However when connecting a PS3 on the router and let it test the router capabilities, the router fails the UPnP testing. In my opinion, this is inexcusable when you sell a product at premium price and you market it as a "gaming" router, you would expect the company to have tested it with all the mainstream consoles.</p>
<div style="margin-left:-12px;">
<script type="text/javascript"><!--
google_ad_client = "pub-7161506883656516";
google_ad_slot = "4834751127";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<p>I have contacted Cisco/Linksys customer support chat service to report the problem and get assistance and basically, I have been told something like that the problem was my fault and that I had to change some obscure and unrelated WiFi settings to fix my problem.</p>

<p>I was not satisfied by the answer and I decided to see for myself why the PS3 is reporting a UPnP failure with that router.</p>

<p>2 tools have been required for the analysis.</p>

<ol>
  <li><a href="http://www.wireshark.org/">Wireshark</a></li>
  <li>An Ethernet hub</li>
</ol>

<p>A hub is a piece of networking hardware allowing you to share an Ethernet link between more than 2 network devices. Those were common in the 90s when processing power and memory were expensive. Today they have been replaced by the more robust and powerful Ethernet switches. My setup has been to plug my PC between the Linksys router and my PS3 and let Wireshark running on my PC sniff the UPnP exchange between them.</p>

<p>Before going in the details of the PS3 UPnP test, I want to share some interesting details about the whole PS3 Internet testing which is close to be undocumented on the Internet</p>

<p>Testing Internet Connection:</p>

<p>It does it by doing a HTTP request on fus01.ps3.update.playstation.net.</p>

<p><code><br />
GET /update/ps3/list/us/ps3-updatelist.txt HTTP/1.1<br />
Host: fus01.ps3.update.playstation.net<br />
Connection: Keep-Alive<br />
Accept-Encoding: identity<br />
User-Agent: PS3Update-agent/1.0.0 libhttp/1.0.0<br />
<br />
HTTP/1.1 200 OK<br />
Server: Apache<br />
ETag: "4d8c4dbf774c6349ad778577e53bd8c7:1285037260"<br />
Last-Modified: Tue, 21 Sep 2010 02:47:40 GMT<br />
Accept-Ranges: bytes<br />
Content-Length: 252<br />
Content-Type: text/plain<br />
Date: Mon, 06 Dec 2010 03:22:33 GMT<br />
Connection: keep-alive<br />
<br />
# US<br />
Dest=84;CompatibleSystemSoftwareVersion=3.5000-;<br />
Dest=84;ImageVersion=0000b437;SystemSoftwareVersion=3.5000;CDN=http://dus01.ps3.update.playstation.net/update/ps3/image/us/2010_0921_0215e26d1dadeb950471a9c3397a140a/PS3UPDAT.PUP;CDN_Timeout=30;<br />
</code></p>

<p>Test PSN connection:</p>

<p>It does so by establishing an HTTPS connection with auth.np.ac.playstation.net. Obviously since it is encrypted, I cannot comment much about it.</p>

<p>NAT Type testing.</p>

<p>The PS3 sends a series of STUN (Session Traversal Utilities for NAT) (<a href="http://blog.olivierlanglois.net/index.php/2007/05/23/nat_traversal_for_the_dummies_and_the_be">I am mentionning STUN in another blog entry for the curious</a>) requests to us.np.stun.playstation.net</p>

<p>So now, lets get back to the UPnP testing. Here is a short overview of the whole procedure:</p>

<ul>
  <li>Broadcast a request to find all network devices that are a InternetGatewayDevice</li>
  <li>Query its capability by requesting a XML file</li>
  <li>If the service WANIPConnection is supported, continue the test</li>
  <li>Call GetExternalIPAddress to obtain the router public Internet IP address</li>
  <li>Call AddPortMapping to open a public port on which all inbound traffic will be forwarded to the PS3</li>
</ul>

<p>Here is how goes the exchange with the WRT330N router:</p>

<p><code><br />
PS3 Broadcast:<br />
<br />
M-SEARCH * HTTP/1.1<br />
HOST: 239.255.255.250:1900<br />
MAN: "ssdp:discover"<br />
MX: 5<br />
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1<br />
</code><br />
2 seconds timeout. Retransmit the same request</p>

<p>After about 1.5 seconds after the 2nd retransmission, the router finally reply:<br />
<code><br />
HTTP/1.1 200 OK<br />
EXT:<br />
SERVER: ipOS/7.2, UPnP/1.0, ipSSDPDevice/1.0<br />
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1<br />
LOCATION: <a href="http://192.168.1.1/root.sxml">http://192.168.1.1/root.sxml</a><br />
CACHE-CONTROL: max-age=1800<br />
USN: uuid:1C7AE0B4-AF9D-3FD9-AC27-04FAE3357DD5::urn:schemas-upnp-org:device:InternetGatewayDevice:1<br />
Content-Length: 0<br />
</code><br />
PS3 request this:<br />
<code><br />
GET /root.sxml HTTP/1.1<br />
HOST: 192.168.1.1:80<br />
</code><br />
PS3 UPnP request:<br />
<code><br />
POST /wipconn HTTP/1.1<br />
HOST: 192.168.1.1:4444<br />
Content-Length: 290<br />
Content-Type: text/xml; charset="utf-8"<br />
SOAPACTION: "urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress"</p>

&lt;s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&gt;<br />
   &lt;s:Body&gt;<br />
      &lt;u:GetExternalIPAddress xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"&gt;<br />
      &lt;/u:GetExternalIPAddress&gt;<br />
   &lt;/s:Body&gt;<br />
&lt;/s:Envelope&gt;<br />
</code>
<p>Linksys Router:<br />
<code><br />
HTTP/1.1 200 OK<br />
SERVER: ipOS/6.8 UPnP/1.0 IGD/1.0<br />
EXT: <br />
Transfer-Encoding: Chunked<br />
<br />
197<br />
&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?>&lt;soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&gt;&lt;soap:Body&gt;&lt;u:GetExternalIPAddressResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"&gt;&lt;NewExternalIPAddress&gt;xxx.xxx.xxx.xxx&lt;/NewExternalIPAddress&gt;&lt;/u:GetExternalIPAddressResponse&gt;&lt;/soap:Body&gt;&lt;/soap:Envelope&gt;<br />
0<br />
</code><br />
2nd PS3 UPnP request:<br />
<code><br />
POST /wipconn HTTP/1.1<br />
HOST: 192.168.1.1:4444<br />
Content-Length: 644<br />
Content-Type: text/xml; charset="utf-8"<br />
SOAPACTION: "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"<br />
<br />
&lt;s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&gt;<br />
   &lt;s:Body&gt;<br />
      &lt;u:AddPortMapping xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"&gt;<br />
 &lt;NewRemoteHost&gt;&lt;/NewRemoteHost&gt;<br />
 &lt;NewExternalPort&gt;3658&lt;/NewExternalPort&gt;<br />
 &lt;NewProtocol&gt;UDP&lt;/NewProtocol&gt;<br />
 &lt;NewInternalPort&gt;3658&lt;/NewInternalPort&gt;<br />
 &lt;NewInternalClient&gt;192.168.1.109&lt;/NewInternalClient&gt;<br />
 &lt;NewEnabled&gt;1&lt;/NewEnabled&gt;<br />
 &lt;NewPortMappingDescription&gt;192.168.1.109:3658 to 3658 (UDP)&lt;/NewPortMappingDescription&gt;<br />
 &lt;NewLeaseDuration&gt;0&lt;/NewLeaseDuration&gt;<br />
      &lt;/u:AddPortMapping&gt;<br />
   &lt;/s:Body&gt;<br />
&lt;/s:Envelope&gt;<br />
</code><br />
Linksys Router:<br />
<code><br />
HTTP/1.1 200 OK<br />
SERVER: ipOS/6.8 UPnP/1.0 IGD/1.0<br />
EXT: <br />
Transfer-Encoding: Chunked<br />
151<br />
&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?>&lt;soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&gt;&lt;soap:Body>&lt;u:AddPortMappingResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"&gt;&lt;/u:AddPortMappingResponse&gt;&lt;/soap:Body>&lt;/soap:Envelope&gt;<br />
0<br />
</code></p>

<p>By looking the exchange it looks all good and in the router log, there is even an entry that shows that the Port mapping occured:</p>

<p><code><br />
[INFO] Sun Dec 05 20:40:09 2010 UPnP renew entry 255.255.255.255 &lt;-&gt; 24.37.208.168:3658 &lt;-&gt; 192.168.1.109:3658 UDP timeout:-1 '192.168.1.109:3658 to 3658 (UDP)'<br />
</code></p>

<p>I initially believed that the error is the returned length of the router reply for the AddPortMapping request. It reports a length of 151 bytes but if you count them, I come to something around 340 chars! The GetExternalIPAddress call has the same problem. The reported size is 197 while in fact, I count around 410 chars!</p>

<p>However, a coworker of mine pointed out to me that the chunk size values are in hex as described in the <a href="http://www.faqs.org/rfcs/rfc2616.html">RFC 2616</a>. So I can only conclude that the problem comes from the PS3 that does not handle correctly HTTP chunked transfer coding in the context of UPnP exchange.</p>

<p>Another indication that the chunked transfer encoding in the replies is the culprit of the problem, it is that at the end of both exchange between the PS3 and the WRT330N is that the PS3 is sending back TCP RST segments to the router which means that the PS3 is closing its connection with the router before the router having finished to send its replies.</p>

<p>For your reference, here is an exchange with my new NetGear router, the <a href="http://www.amazon.com/gp/product/B003Q9CI48?ie=UTF8&amp;tag=olivielanglos-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B003Q9CI48">WNDR37AV</a> that works like a charm!</p>

<p><code><br />
In less than 2 ms the reply to the M-SEARCH query comes back.<br />
<br />
HTTP/1.1 200 OK<br />
Cache-Control: max-age=1800<br />
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1<br />
USN: uuid:12345678-0000-0000-0000-00000000abcd::urn:schemas-upnp-org:device:InternetGatewayDevice:1<br />
EXT:<br />
Server: Linux/2.6.15-1.2054_FC5 UPnP/1.0 miniupnpd/1.0<br />
Location: <a href="http://192.168.1.1:5555/rootDesc.xml">http://192.168.1.1:5555/rootDesc.xml</a><br />
<br />
PS3 request this:<br />
<br />
GET /rootDesc.xml HTTP/1.1<br />
HOST: 192.168.1.1:5555<br />
<br />
PS3 UPnP request:<br />
<br />
POST /ctl/IPConn HTTP/1.1<br />
HOST: 192.168.1.1:5555<br />
Content-Length: 290<br />
Content-Type: text/xml; charset="utf-8"<br />
SOAPACTION: "urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress"<br />
<br />
&lt;s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&gt;<br />
   &lt;s:Body&gt;<br />
      &lt;u:GetExternalIPAddress xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"&gt;<br />
      &lt;/u:GetExternalIPAddress&gt;<br />
   &lt;/s:Body&gt;<br />
&lt;/s:Envelope&gt;<br />
<br />
Netgear reply:<br />
<br />
HTTP/1.1 200 OK<br />
Content-Type: text/xml; charset="utf-8"<br />
Connection: close<br />
Content-Length: 356<br />
Server: Linux/2.6.15-1.2054_FC5 UPnP/1.0 miniupnpd/1.0<br />
Ext:<br />
<br />
&lt;?xml version="1.0"?&gt;<br />
&lt;s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&gt;&lt;s:Body&gt;&lt;u:GetExternalIPAddressResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"&gt;&lt;NewExternalIPAddress&gt;xxx.xxx.xxx.xxx&lt;/NewExternalIPAddress&gt;&lt;/u:GetExternalIPAddressResponse&gt;&lt;/s:Body&gt;&lt;/s:Envelope&gt;<br />
<br />
2nd PS3 UPnP request:<br />
POST /ctl/IPConn HTTP/1.1<br />
HOST: 192.168.1.1:5555<br />
Content-Length: 644<br />
Content-Type: text/xml; charset="utf-8"<br />
SOAPACTION: "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"<br />
<br />
&lt;s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&gt;<br />
   &lt;s:Body&gt;<br />
      &lt;u:AddPortMapping xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"&gt;<br />
 &lt;NewRemoteHost&gt;&lt;/NewRemoteHost&gt;<br />
 &lt;NewExternalPort&gt;3658&lt;/NewExternalPort&gt;<br />
 &lt;NewProtocol&gt;UDP&lt;/NewProtocol&gt;<br />
 &lt;NewInternalPort&gt;3658&lt;/NewInternalPort&gt;<br />
 &lt;NewInternalClient&gt;192.168.1.109&lt;/NewInternalClient&gt;<br />
 &lt;NewEnabled&gt;1&lt;/NewEnabled&gt;<br />
 &lt;NewPortMappingDescription&gt;192.168.1.109:3658 to 3658 (UDP)&lt;/NewPortMappingDescription&gt;<br />
 &lt;NewLeaseDuration&gt;0&lt;/NewLeaseDuration&gt;<br />
      &lt;/u:AddPortMapping&gt;<br />
   &lt;/s:Body&gt;<br />
&lt;/s:Envelope&gt;<br />
<br />
Netgear reply:<br />
<br />
HTTP/1.1 200 OK<br />
Content-Type: text/xml; charset="utf-8"<br />
Connection: close<br />
Content-Length: 260<br />
Server: Linux/2.6.15-1.2054_FC5 UPnP/1.0 miniupnpd/1.0<br />
Ext:<br />
<br />
&lt;?xml version="1.0"?&gt;<br />
&lt;s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&gt;&lt;s:Body&gt;&lt;u:AddPortMappingResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"/&gt;<br />
&lt;/s:Body&gt;<br />
&lt;/s:Envelope&gt;<br />
</code></p>
<div style="margin-left:-12px;">
<script type="text/javascript"><!--
google_ad_client = "pub-7161506883656516";
google_ad_slot = "4834751127";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<p>In conclusion, I am disapointed by the quality of the Linksys product and the lack of attention of details that the company did put in the QA before the release of that product since the UPnP bug could have been caught by a very simple test in less than 5 minutes. Apparently the bug is in the PS3 that does not support UPnP interaction with HTTP replies using chunked transfer coding but I was expecting to purchase a router compatible with my PS3 when I bought a gaming router. For that reason, I prefer the NetGear router.</p>

<p>Happy networking!</p>]]></content:encoded>
					<comments>http://blog.olivierlanglois.net/index.php?p=169&amp;c=1&amp;tb=1&amp;pb=1#comments</comments>
				</item>
								<item>
					<title>Graph breadth-first traversal algorithm C++ implementation</title>
					<link>http://blog.olivierlanglois.net/index.php/2010/08/24/graph_breadth_first_traversal_algorithm_</link>
					<pubDate>Wed, 25 Aug 2010 02:53:31 +0000</pubDate>
					<dc:creator>lano1106</dc:creator>
					<category domain="main">General</category>
<category domain="alt">C++</category>					<guid isPermaLink="false">168@http://blog.olivierlanglois.net/</guid>
					<description>I have posted on my website a small C++ program that I have been asked to write during an interview with Facebook at Fall 2009. One of their interview was related to graph theory and the problem was to find the the shortest distance between to nodes in a graph. The best algorithm to use to solve this problem is the breadth-first traversal algorithm.


You can look at the source code here at:
http://www.olivierlanglois.net/archive/graph_cpp.htm


and you can read more about the breadth-first traversal algorithm in Robert Sedgewick excellent book on algorithms.
</description>
					<content:encoded><![CDATA[<p>I have posted on my website a small C++ program that I have been asked to write during an interview with Facebook at Fall 2009. One of their interview was related to graph theory and the problem was to find the the shortest distance between to nodes in a graph. The best algorithm to use to solve this problem is the breadth-first traversal algorithm.</p>
<!-- Adsense block #3 not displayed since it exceed the limit of 2 -->

<p>You can look at the source code here at:<br />
<a href="http://www.olivierlanglois.net/archive/graph_cpp.htm">http://www.olivierlanglois.net/archive/graph_cpp.htm</a></p>


<p>and you can read more about the breadth-first traversal algorithm in <a href="http://www.amazon.com/gp/product/020172684X?ie=UTF8&amp;tag=olivielanglos-20&amp;link_code=as3&amp;camp=211189&amp;creative=373489&amp;creativeASIN=020172684X">Robert Sedgewick excellent book on algorithms</a>.</p>
]]></content:encoded>
					<comments>http://blog.olivierlanglois.net/index.php?p=168&amp;c=1&amp;tb=1&amp;pb=1#comments</comments>
				</item>
								<item>
					<title>A new page in my career</title>
					<link>http://blog.olivierlanglois.net/index.php/2010/06/01/a_new_page_in_my_career_1</link>
					<pubDate>Wed, 02 Jun 2010 02:41:06 +0000</pubDate>
					<dc:creator>lano1106</dc:creator>
					<category domain="main">General</category>					<guid isPermaLink="false">167@http://blog.olivierlanglois.net/</guid>
					<description>Today was my last day at StreamTheWorld. I spent the last 3 years there as the company C++ Tech Lead in charge of the company C++ streaming servers development. It has been a nice ride filled with challenges.These servers are used by over 1600 radio stations including AOL/CBS radios accessible through Winamp and Flash players.

Among my various realizations. There are:

  Scale and improve the performance and the reliability of the company audio/video streaming servers to the point where it can concurrently handles hundreds of thousands of live feeds every day in more than 25 countries, including during peak audience dayparts. The reliability and the quality of the server software have been proven to such industry leaders as CBS, Entercom, Multimedios, AOL and more. This represents 20x improvement over the original capacity.
  Added more functionality to the server by growing the server code base from 25K lines in June 2007 to 200K lines in only 2 years while improving robustness and performance.
  Designed and implemented a high performance targetted stream ad insertion system that serve end-user ads based geoip lookup. This system is now used by ESPN Radio on Internet.
  Design and implement a protocol stack to support Adobe proprietary protocol RTMP clients
  Add AAC support to the streaming server
  Improve Microsoft MediaPlayer and Silverlight support.


I will start my new job Monday next week. Visit back my blog or my LinkedIn profile if you are curious to learn for which amazing new employer I will be working for.

</description>
					<content:encoded><![CDATA[<p>Today was my last day at StreamTheWorld. I spent the last 3 years there as the company C++ Tech Lead in charge of the company C++ streaming servers development. It has been a nice ride filled with challenges.These servers are used by over 1600 radio stations including AOL/CBS radios accessible through Winamp and Flash players.</p>

<p>Among my various realizations. There are:</p>
<ul>
  <li>Scale and improve the performance and the reliability of the company audio/video streaming servers to the point where it can concurrently handles hundreds of thousands of live feeds every day in more than 25 countries, including during peak audience dayparts. The reliability and the quality of the server software have been proven to such industry leaders as CBS, Entercom, Multimedios, AOL and more. This represents 20x improvement over the original capacity.</li>
  <li>Added more functionality to the server by growing the server code base from 25K lines in June 2007 to 200K lines in only 2 years while improving robustness and performance.</li>
  <li>Designed and implemented a high performance targetted stream ad insertion system that serve end-user ads based geoip lookup. This system is now used by ESPN Radio on Internet.</li>
  <li>Design and implement a protocol stack to support Adobe proprietary protocol RTMP clients</li>
  <li>Add AAC support to the streaming server</li>
  <li>Improve Microsoft MediaPlayer and Silverlight support.</li>
</ul>
<!-- Adsense block #4 not displayed since it exceed the limit of 2 -->
<p>I will start my new job Monday next week. Visit back my blog or my <a href="http://ca.linkedin.com/in/olivierlanglois">LinkedIn profile</a> if you are curious to learn for which amazing new employer I will be working for.</p>

]]></content:encoded>
					<comments>http://blog.olivierlanglois.net/index.php?p=167&amp;c=1&amp;tb=1&amp;pb=1#comments</comments>
				</item>
								<item>
					<title>Large Scale C++ Software Design</title>
					<link>http://blog.olivierlanglois.net/index.php/2010/05/24/large_scale_c_software_design</link>
					<pubDate>Mon, 24 May 2010 19:43:47 +0000</pubDate>
					<dc:creator>lano1106</dc:creator>
					<category domain="main">C++</category>					<guid isPermaLink="false">166@http://blog.olivierlanglois.net/</guid>
					<description>
It is a very interesting book. Anyone having been involved in a large scale software development projects will recognize typical problems often seen in this type of projects while reading this book and by experience we have developed an intuition about how to deal with the complexity inherent to large scale projects. Mr Lakos book is the first, to my knowledge, that address this subject and it formalize extremely well the problems of large scale projects and propose a methodology and principles to apply to keep the development and maintainability of these projects manageable. It is a very refreshing C++ book and I recommend it to any C++ professionals not having read it yet.

The most interesting chapters in my opinion are chapter 5 and chapter 6. Chapter 5 presents refactoring methods to remove cyclical dependencies among components, reduce inter dependencies and how to layout components into software layers that will ease reusability and maintainability. Chapter 6 discuss about component insulation. Its difference with encapsulation, the benefits of component insulation and its cost and when it is wise to avoid insulation.

</description>
					<content:encoded><![CDATA[<div><a href="http://www.amazon.com/gp/product/0201633620?ie=UTF8&amp;tag=olivielanglos-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0201633620"><img src="http://blog.olivierlanglois.net/media/blogs/olivier_blog/Large_Scale_cpp_Software_Design.jpg" alt="Large-Scale C++ Software Design, John Lakos, ISBN:0201633620" title="" width="100" height="124" /></a></div>
<p>It is a very interesting book. Anyone having been involved in a large scale software development projects will recognize typical problems often seen in this type of projects while reading this book and by experience we have developed an intuition about how to deal with the complexity inherent to large scale projects. Mr Lakos book is the first, to my knowledge, that address this subject and it formalize extremely well the problems of large scale projects and propose a methodology and principles to apply to keep the development and maintainability of these projects manageable. It is a very refreshing C++ book and I recommend it to any C++ professionals not having read it yet.</p>
<!-- Adsense block #5 not displayed since it exceed the limit of 2 -->
<p>The most interesting chapters in my opinion are chapter 5 and chapter 6. Chapter 5 presents refactoring methods to remove cyclical dependencies among components, reduce inter dependencies and how to layout components into software layers that will ease reusability and maintainability. Chapter 6 discuss about component insulation. Its difference with encapsulation, the benefits of component insulation and its cost and when it is wise to avoid insulation.</p>

]]></content:encoded>
					<comments>http://blog.olivierlanglois.net/index.php?p=166&amp;c=1&amp;tb=1&amp;pb=1#comments</comments>
				</item>
								<item>
					<title>My new C++ source code to HTML converter</title>
					<link>http://blog.olivierlanglois.net/index.php/2010/05/24/my_new_c_source_code_to_html_converter</link>
					<pubDate>Mon, 24 May 2010 18:56:55 +0000</pubDate>
					<dc:creator>lano1106</dc:creator>
					<category domain="main">General</category>					<guid isPermaLink="false">165@http://blog.olivierlanglois.net/</guid>
					<description>While I was integrating a fix to a bug that has been reported to me by Daniel Quadros in my primality testing C++ module and also adding gcc asm support to it. I used that opportunity to rework my C++ source code to HTML converter. The 2 things that I added to the converter are:


  replace the usage of the &#60;font&#62; tags with &#60;span&#62; tags in combination of CSS classes
  size optimization of the converted document


The size optimization came from the very simple observation that my converter was stateless and was not recognizing when multiple consecutive sections sharing the same colors were processed. I just added a small FSM to my converter to keep track of the current state and the converter now close the current tag only if there is a transition to a new color. The most impressive result came from my DCEL C++ file with a 25% file size reduction!

Also, I am just starting to appreciate to power of CSS. I will now be able to change the code snippet colors across my whole website by just updating a small CSS file. As a side bonus by having switched from the &#60;font&#62; tags to &#60;span&#62;, I can now use my C++ highlight feature in the code snippets contained in this blog as the blog engine was forbiding using &#60;font&#62; tags on posts but allows &#60;span&#62;.</description>
					<content:encoded><![CDATA[<p>While I was integrating a fix to a bug that has been reported to me by Daniel Quadros in my <a href="http://www.olivierlanglois.net/archive/prime_cpp.htm">primality testing C++ module</a> and also adding gcc asm support to it. I used that opportunity to rework my C++ source code to HTML converter. The 2 things that I added to the converter are:</p>

<ul>
  <li>replace the usage of the &lt;font&gt; tags with &lt;span&gt; tags in combination of <a href="http://blog.olivierlanglois.net/index.php/2010/03/25/cascading_style_sheet_the_definitive_gui">CSS</a> classes</li>
  <li>size optimization of the converted document</li>
</ul>
<!-- Adsense block #6 not displayed since it exceed the limit of 2 -->
<p>The size optimization came from the very simple observation that my converter was stateless and was not recognizing when multiple consecutive sections sharing the same colors were processed. I just added a small <a href="http://blog.olivierlanglois.net/index.php/2007/07/11/practical_statecharts_in_c_c_quantum_pro">FSM</a> to my converter to keep track of the current state and the converter now close the current tag only if there is a transition to a new color. The most impressive result came from my <a href="http://www.olivierlanglois.net/archive/dcel_cpp.htm">DCEL C++ file</a> with a 25% file size reduction!</p>

<p>Also, I am just starting to appreciate to power of <a href="http://blog.olivierlanglois.net/index.php/2010/03/25/cascading_style_sheet_the_definitive_gui">CSS</a>. I will now be able to change the code snippet colors across my whole website by just updating a small <a href="http://blog.olivierlanglois.net/index.php/2010/03/25/cascading_style_sheet_the_definitive_gui">CSS</a> file. As a side bonus by having switched from the &lt;font&gt; tags to &lt;span&gt;, I can now use my C++ highlight feature in the <a href="http://blog.olivierlanglois.net/index.php?cat=16">code snippets contained in this blog</a> as the blog engine was forbiding using &lt;font&gt; tags on posts but allows &lt;span&gt;.</p>]]></content:encoded>
					<comments>http://blog.olivierlanglois.net/index.php?p=165&amp;c=1&amp;tb=1&amp;pb=1#comments</comments>
				</item>
					</channel>
</rss>

