[rtmpdump] r19 - rtmp.cpp rtmp.h rtmpdump.cpp

hyc subversion at mplayerhq.hu
Mon Nov 2 03:51:17 CET 2009


Author: hyc
Date: Mon Nov  2 03:51:17 2009
New Revision: 19

Log:
SOCKS4 support from Monsieur Video

Modified:
   rtmp.cpp
   rtmp.h
   rtmpdump.cpp

Modified: rtmp.cpp
==============================================================================
--- rtmp.cpp	Sat Oct 31 03:49:17 2009	(r18)
+++ rtmp.cpp	Mon Nov  2 03:51:17 2009	(r19)
@@ -129,6 +129,7 @@ void CRTMP::SetupStream(
 	int protocol, 
 	const char *hostname, 
 	unsigned int port, 
+        const char *sockshost,
 	const char *playpath, 
 	const char *tcUrl, 
 	const char *swfUrl, 
@@ -182,6 +183,20 @@ void CRTMP::SetupStream(
 	Link.SWFSize = 0;
   }
 
+  if(sockshost)
+  {
+    const char *socksport = strchr(sockshost, ':');
+
+    Link.sockshost = strndup(sockshost,
+        socksport ? socksport - sockshost : strlen(sockshost));
+    Link.socksport = socksport ? atoi(socksport + 1) : 1080;
+    Log(LOGDEBUG, "Connecting via SOCKS proxy: %s:%d", Link.sockshost, Link.socksport);
+  } else {
+    Link.sockshost = NULL;
+    Link.socksport = 0;
+  }
+
+
   Link.tcUrl = tcUrl;
   Link.swfUrl = swfUrl;
   Link.pageUrl = pageUrl;
@@ -202,6 +217,24 @@ void CRTMP::SetupStream(
     Link.port = 1935;
 }
 
+static bool add_addr_info(sockaddr_in* service, const char *hostname, int port)
+{
+  service->sin_addr.s_addr = inet_addr(hostname);
+  if (service->sin_addr.s_addr == INADDR_NONE)
+  {
+    struct hostent *host = gethostbyname(hostname);
+    if (host == NULL || host->h_addr == NULL)
+    {
+      Log(LOGERROR, "Problem accessing the DNS. (addr: %s)", hostname);
+      return false;
+    }
+    service->sin_addr = *(struct in_addr*)host->h_addr;
+  }
+
+  service->sin_port = htons(port);
+  return true;
+}
+
 bool CRTMP::Connect() {
   if (!Link.hostname)
      return false;
@@ -215,19 +248,16 @@ bool CRTMP::Connect() {
   sockaddr_in service;
   memset(&service, 0, sizeof(sockaddr_in));
   service.sin_family = AF_INET;
-  service.sin_addr.s_addr = inet_addr(Link.hostname);
-  if (service.sin_addr.s_addr == INADDR_NONE)
+
+  if (Link.socksport)
   {
-    struct hostent *host = gethostbyname(Link.hostname);
-    if (host == NULL || host->h_addr == NULL)
-    {
-      Log(LOGERROR, "Problem accessing the DNS. (addr: %s)", Link.hostname);
-      return false;
-    }
-    service.sin_addr = *(struct in_addr*)host->h_addr;
+    // Connect via SOCKS
+    if(!add_addr_info(&service, Link.sockshost, Link.socksport)) return false;
+  } else {
+    // Connect directly
+    if(!add_addr_info(&service, Link.hostname, Link.port)) return false;
   }
 
-  service.sin_port = htons(Link.port);
   m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
   if (m_socket != -1)
   {
@@ -240,6 +270,16 @@ bool CRTMP::Connect() {
       return false;
     }
 
+    if(Link.socksport) {
+      Log(LOGDEBUG, "%s ... SOCKS negotiation", __FUNCTION__);
+      if (!SocksNegotiate())
+      {
+        Log(LOGERROR, "%s, SOCKS negotiation failed.", __FUNCTION__);
+        Close();
+        return false;
+      }
+    }
+
     Log(LOGDEBUG, "%s, ... connected, handshaking", __FUNCTION__);
     if (!HandShake())
     {
@@ -274,6 +314,35 @@ bool CRTMP::Connect() {
   return true;
 }
 
+bool CRTMP::SocksNegotiate() {
+  char packet[255];
+  sockaddr_in service;
+  memset(&service, 0, sizeof(sockaddr_in));
+
+  add_addr_info(&service, Link.hostname, Link.port);
+  unsigned long addr = htonl(service.sin_addr.s_addr);
+
+  int len = snprintf(packet, sizeof packet, "%c%c%c%c%c%c%c%c%c",
+      4, 1, // SOCKS 4, connect
+      (Link.port  >> 8) & 0xFF,
+      (Link.port) & 0xFF,
+      (char) (addr >> 24) & 0xFF, (char) (addr >> 16) & 0xFF,
+      (char) (addr >> 8)  & 0xFF, (char) addr & 0xFF,
+      0); // NULL terminate
+
+  WriteN(packet, len);
+
+  if(ReadN(packet, 8) != 8)
+    return false;
+
+  if(packet[0] == 0 && packet[1] == 90) {
+    return true;
+  } else {
+    Log(LOGERROR, "%s, SOCKS returned error code %d", packet[1]);
+    return false;
+  }
+}
+
 bool CRTMP::ConnectStream(double seekTime) {
   if (seekTime >= -2.0)
     Link.seekTime = seekTime;

Modified: rtmp.h
==============================================================================
--- rtmp.h	Sat Oct 31 03:49:17 2009	(r18)
+++ rtmp.h	Mon Nov  2 03:51:17 2009	(r19)
@@ -99,7 +99,10 @@ typedef struct
 
 	//char SWFHashHMAC[32];
 	char SWFVerificationResponse[42];
-	#endif	
+	#endif
+
+        const char *sockshost;
+        unsigned short socksport;
 } LNK;
 
 class CRTMP
@@ -116,6 +119,7 @@ class CRTMP
       	int protocol, 
 	const char *hostname, 
 	unsigned int port, 
+        const char *sockshost,
 	const char *playpath, 
 	const char *tcUrl, 
 	const char *swfUrl, 
@@ -164,6 +168,7 @@ class CRTMP
     protected:
       bool HandShake(bool FP9HandShake=true);
       bool RTMPConnect();
+      bool SocksNegotiate();
 
       bool SendConnectPacket();
       bool SendServerBW();

Modified: rtmpdump.cpp
==============================================================================
--- rtmpdump.cpp	Sat Oct 31 03:49:17 2009	(r18)
+++ rtmpdump.cpp	Mon Nov  2 03:51:17 2009	(r19)
@@ -874,6 +874,7 @@ int main(int argc, char **argv)
 	char *swfHash = 0;
 	uint32_t swfSize = 0;
 	char *flashVer = 0;
+        char *sockshost = 0;
 
 	char *flvFile = 0;
 
@@ -900,6 +901,7 @@ int main(int argc, char **argv)
 		{"help",    0, NULL, 'h'},
 		{"host",    1, NULL, 'n'},
 		{"port",    1, NULL, 'c'},
+		{"socks",   1, NULL, 'S'},
 		{"protocol",1, NULL, 'l'},
 		{"playpath",1, NULL, 'y'},
 		{"rtmp",    1, NULL, 'r'},
@@ -926,7 +928,7 @@ int main(int argc, char **argv)
 		{0,0,0,0}
 	};
 
-	while((opt = getopt_long(argc, argv, "hVveqzr:s:t:p:a:f:o:u:n:c:l:y:m:k:d:A:B:w:x:", longopts, NULL)) != -1) {
+	while((opt = getopt_long(argc, argv, "hVveqzr:s:t:p:a:f:o:u:n:c:l:y:m:k:d:A:B:w:x:S:", longopts, NULL)) != -1) {
 		switch(opt) {
 			case 'h':
 				LogPrintf("\nThis program dumps the media content streamed over rtmp.\n\n");
@@ -934,6 +936,7 @@ int main(int argc, char **argv)
 				LogPrintf("--rtmp|-r url           URL (e.g. rtmp//hotname[:port]/path)\n");
 				LogPrintf("--host|-n hostname      Overrides the hostname in the rtmp url\n");
 				LogPrintf("--port|-c port          Overrides the port in the rtmp url\n");
+				LogPrintf("--socks|-S host:port    Use the specified SOCKS proxy\n");
 				LogPrintf("--protocol|-l           Overrides the protocol in the rtmp url (0 - RTMP, 3 - RTMPE)\n");
 				LogPrintf("--playpath|-y           Overrides the playpath parsed from rtmp url\n");
 				LogPrintf("--swfUrl|-s url         URL to player swf file\n");
@@ -1095,6 +1098,9 @@ int main(int argc, char **argv)
 			case 'z':
 				debuglevel = LOGALL;
 				break;
+                        case 'S':
+                                sockshost = optarg;
+				break;
 			default:
 				LogPrintf("unknown option: %c\n", opt);
 				break;
@@ -1177,7 +1183,7 @@ int main(int argc, char **argv)
 	memset(buffer, 0, bufferSize);
 
 	CRTMP  *rtmp = new CRTMP();
-	rtmp->SetupStream(protocol, hostname, port, playpath, tcUrl, swfUrl,
+	rtmp->SetupStream(protocol, hostname, port, sockshost, playpath, tcUrl, swfUrl,
 		pageUrl, app, auth, swfHash, swfSize, flashVer, subscribepath,
 		dSeek, bLiveStream, timeout);
 


More information about the rtmpdump mailing list