From 5fb7e235b50d41d9dd108cf77ca0778c3445dfd7 Mon Sep 17 00:00:00 2001
From: Thulinma <jaron@vietors.com>
Date: Mon, 12 Mar 2012 15:49:19 +0100
Subject: [PATCH] Fixed several FLV-related server bugs.

---
 Buffer/main.cpp         |  6 +++---
 Connector_RTMP/main.cpp | 28 +++++++++++++++++++------
 util/flv_tag.cpp        | 46 ++++++++++++++++++++++++++---------------
 3 files changed, 54 insertions(+), 26 deletions(-)

diff --git a/Buffer/main.cpp b/Buffer/main.cpp
index b822f067..a99969cb 100644
--- a/Buffer/main.cpp
+++ b/Buffer/main.cpp
@@ -362,7 +362,7 @@ namespace Buffer{
               if (tmp != ""){
                 if (tmp[0] == 'P'){
                   std::cout << "Push attempt from IP " << tmp.substr(2) << std::endl;
-                  if (tmp.substr(2) == waiting_ip){
+                  if (tmp.substr(2) == waiting_ip || tmp.substr(2) == "::ffff:"+waiting_ip){
                     if (!ip_input.connected()){
                       std::cout << "Push accepted!" << std::endl;
                       ip_input = (*usersIt).S;
@@ -372,7 +372,7 @@ namespace Buffer{
                       (*usersIt).Disconnect("Push denied - push already in progress!");
                     }
                   }else{
-                    (*usersIt).Disconnect("Push denied - invalid IP address!");
+                    (*usersIt).Disconnect("Push denied - invalid IP address ("+waiting_ip+"!="+tmp.substr(2)+")!");
                   }
                 }
                 if (tmp[0] == 'S'){
@@ -399,7 +399,7 @@ namespace Buffer{
 
     // disconnect listener
     if (FLV::Parse_Error){
-      std::cout << "FLV parse error" << std::endl;
+      std::cout << "FLV parse error:" << FLV::Error_Str << std::endl;
     }else{
       std::cout << "Reached EOF of input" << std::endl;
     }
diff --git a/Connector_RTMP/main.cpp b/Connector_RTMP/main.cpp
index b55b563c..28a9622b 100644
--- a/Connector_RTMP/main.cpp
+++ b/Connector_RTMP/main.cpp
@@ -241,21 +241,31 @@ void Connector_RTMP::parseChunk(){
         Socket.write(RTMPStream::SendCTL(5, RTMPStream::snd_window_size));//send window acknowledgement size (msg 5)
         break;
       case 8:
-        #if DEBUG >= 4
-        fprintf(stderr, "Received audio data\n");
-        #endif
         F.ChunkLoader(next);
         if (SS.connected()){
+          #if DEBUG >= 4
+          fprintf(stderr, "A");
+          #endif
           SS.write(std::string(F.data, F.len));
+        }else{
+          #if DEBUG >= 4
+          fprintf(stderr, "Received useless audio data\n");
+          #endif
+          Socket.close();
         }
         break;
       case 9:
-        #if DEBUG >= 4
-        fprintf(stderr, "Received video data\n");
-        #endif
         F.ChunkLoader(next);
         if (SS.connected()){
+          #if DEBUG >= 4
+          fprintf(stderr, "V");
+          #endif
           SS.write(std::string(F.data, F.len));
+        }else{
+          #if DEBUG >= 4
+          fprintf(stderr, "Received useless video data\n");
+          #endif
+          Socket.close();
         }
         break;
       case 15:
@@ -348,6 +358,9 @@ void Connector_RTMP::parseChunk(){
             Socket.write(RTMPStream::SendUSR(0, 1));//send UCM StreamBegin (0), stream 1
             parsed3 = true;
           }//createStream
+          if ((amfdata.getContentP(0)->StrValue() == "closeStream") || (amfdata.getContentP(0)->StrValue() == "deleteStream")){
+            if (SS.connected()){SS.close();}
+          }
           if ((amfdata.getContentP(0)->StrValue() == "getStreamLength") || (amfdata.getContentP(0)->StrValue() == "getMovLen")){
             //send a _result reply
             AMF::Object amfreply("container", AMF::AMF0_DDV_CONTAINER);
@@ -569,6 +582,9 @@ void Connector_RTMP::parseChunk(){
           Socket.write(RTMPStream::SendUSR(0, 1));//send UCM StreamBegin (0), stream 1
           parsed = true;
         }//createStream
+        if ((amfdata.getContentP(0)->StrValue() == "closeStream") || (amfdata.getContentP(0)->StrValue() == "deleteStream")){
+          if (SS.connected()){SS.close();}
+        }
         if ((amfdata.getContentP(0)->StrValue() == "getStreamLength") || (amfdata.getContentP(0)->StrValue() == "getMovLen")){
           //send a _result reply
           AMF::Object amfreply("container", AMF::AMF0_DDV_CONTAINER);
diff --git a/util/flv_tag.cpp b/util/flv_tag.cpp
index 526de7d0..427b2243 100644
--- a/util/flv_tag.cpp
+++ b/util/flv_tag.cpp
@@ -320,7 +320,14 @@ bool FLV::Tag::MemLoader(char * D, unsigned int S, unsigned int & P){
         len += (data[2] << 8);
         len += (data[1] << 16);
         if (buf < len){data = (char*)realloc(data, len); buf = len;}
-        if (data[0] > 0x12){FLV::Parse_Error = true; Error_Str = "Invalid Tag received."; return false;}
+        if (data[0] > 0x12){
+          data[0] += 32;
+          FLV::Parse_Error = true;
+          Error_Str = "Invalid Tag received (";
+          Error_Str += data[0];
+          Error_Str += ").";
+          return false;
+        }
         done = false;
       }
     }
@@ -347,20 +354,11 @@ bool FLV::Tag::MemLoader(char * D, unsigned int S, unsigned int & P){
 /// \param sock Socket to read from.
 /// \return True if count bytes are read succesfully, false otherwise.
 bool FLV::Tag::SockReadUntil(char * buffer, unsigned int count, unsigned int & sofar, Socket::Connection & sock){
-  if (sofar == count){return true;}
-  if (!sock.read(buffer + sofar,count-sofar)){
-    if (errno != EWOULDBLOCK){
-      FLV::Parse_Error = true;
-      Error_Str = "Error reading from socket.";
-    }
-    return false;
-  }
-  sofar += count-sofar;
-  if (sofar == count){return true;}
-  if (sofar > count){
-    FLV::Parse_Error = true;
-    Error_Str = "Socket buffer overflow.";
-  }
+  if (sofar >= count){return true;}
+  int r = 0;
+  r = sock.iread(buffer + sofar,count-sofar);
+  sofar += r;
+  if (sofar >= count){return true;}
   return false;
 }//Tag::SockReadUntil
 
@@ -387,7 +385,14 @@ bool FLV::Tag::SockLoader(Socket::Connection sock){
         len += (data[2] << 8);
         len += (data[1] << 16);
         if (buf < len){data = (char*)realloc(data, len); buf = len;}
-        if (data[0] > 0x12){FLV::Parse_Error = true; Error_Str = "Invalid Tag received."; return false;}
+        if (data[0] > 0x12){
+          data[0] += 32;
+          FLV::Parse_Error = true;
+          Error_Str = "Invalid Tag received (";
+          Error_Str += data[0];
+          Error_Str += ").";
+          return false;
+        }
         done = false;
       }
     }
@@ -459,7 +464,14 @@ bool FLV::Tag::FileLoader(FILE * f){
         len += (data[2] << 8);
         len += (data[1] << 16);
         if (buf < len){data = (char*)realloc(data, len); buf = len;}
-        if (data[0] > 0x12){FLV::Parse_Error = true; Error_Str = "Invalid Tag received."; return false;}
+        if (data[0] > 0x12){
+          data[0] += 32;
+          FLV::Parse_Error = true;
+          Error_Str = "Invalid Tag received (";
+          Error_Str += data[0];
+          Error_Str += ").";
+          return false;
+        }
         done = false;
       }
     }