News:

Latest versions:
Server plugin: 0.5.1
MVP dongle: 0.5.2
Raspberry Pi client: 0.5.2
Windows client: 0.5.2-1

Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - meinetwegen

#1
This is quite a common problem of vompserver 0.3.1. There already exists a patch for it. You can find it here:

http://www.russle.net/vomp/0.3.1/server/05_client_startup_fail

Unfortunately this project seems to be abandoned so that the patches do not make it into the CVS.

#2
VOMP General / MVP / Re: Vomp on ARM/Marvell
February 21, 2011, 22:14:43
Hi,

This patch fixes the problems described in this thread. They are caused by ARM5 being
incapable of handling unaligned data access. Details can be found here:

http://infocenter.arm.com/help/topic/com.arm.doc.dui0473c/Cihdbfje.html

This patch should be applied to vompserver 0.3.1-3 since the debian-kirkwood system
seems to be especially susceptible to the problem described in the thread below which
has been fixed in 0.3.1-3.

http://forum.loggytronic.com/index.php?topic=528.0



Index: defines.h
===================================================================
--- defines.h (revision 7)
+++ defines.h (working copy)
@@ -32,4 +32,25 @@

typedef int32_t INT;

+/* serializes a numeric host data type into a byte stream in network order (big endian) */
+template<typename T>
+UCHAR* htoncpy(UCHAR* dest, T src)
+{
+  int len = sizeof(T);
+  while (len--)
+    *dest++ = src >> (len * 8);
+  return dest;
+}
+
+/* decodes a byte stream in network order (big endian) into a numeric host data type */
+template<typename T>
+UCHAR* ntohcpy(T& dest, UCHAR* src)
+{
+  dest = *src++;
+  int len = sizeof(T);
+  while (--len)
+    dest = (dest << 8) | *src++;
+  return src;
+}
+
#endif
Index: mvpreceiver.c
===================================================================
--- mvpreceiver.c (revision 7)
+++ mvpreceiver.c (working copy)
@@ -133,10 +133,10 @@
      amountReceived = processed.get(buffer+headerLength, streamChunkSize);
      pthread_mutex_unlock(&processedRingLock);
   
-      *(ULONG*)&buffer[0] = htonl(2); // stream channel
-      *(ULONG*)&buffer[4] = htonl(streamID);
-      *(ULONG*)&buffer[8] = htonl(0); // here insert flag: 0 = ok, data follows
-      *(ULONG*)&buffer[12] = htonl(amountReceived);
+      htoncpy(&buffer[0], 2); // stream channel
+      htoncpy(&buffer[4], streamID);
+      htoncpy(&buffer[8], 0); // here insert flag: 0 = ok, data follows
+      htoncpy(&buffer[12], amountReceived);

      tcp->sendPacket(buffer, amountReceived + headerLength);
    } while(processed.getContent() >= streamChunkSize);
@@ -147,10 +147,10 @@
{
  ULONG bufferLength = sizeof(ULONG) * 4;
  UCHAR buffer[bufferLength];
-  *(ULONG*)&buffer[0] = htonl(2); // stream channel
-  *(ULONG*)&buffer[4] = htonl(streamID);
-  *(ULONG*)&buffer[8] = htonl(1); // stream end
-  *(ULONG*)&buffer[12] = htonl(0); // zero length, no more data
+  htoncpy(&buffer[0], 2); // stream channel
+  htoncpy(&buffer[4], streamID);
+  htoncpy(&buffer[8], 1); // stream end
+  htoncpy(&buffer[12], 0); // zero length, no more data
  tcp->sendPacket(buffer, bufferLength);
}

Index: mvprelay.c
===================================================================
--- mvprelay.c (revision 7)
+++ mvprelay.c (working copy)
@@ -73,7 +73,8 @@

    // Check incoming packet magic number

-    ULONG inMagic = ntohl(*(ULONG*)&in[4]);
+    ULONG inMagic;
+    ntohcpy(inMagic, &in[4]);
    if (inMagic != 0xbabefafe)
    {
      Log::getInstance()->log("MVPRelay", Log::DEBUG, "inMagic not correct");
@@ -81,10 +82,13 @@
    }

    // Get peer info
-    USHORT peerPort = ntohs(*(USHORT*)&in[20]);
+    USHORT peerPort;
+    ntohcpy(peerPort, &in[20]);

    // Get my IP for this connection
-    ULONG myIP = ds.getMyIP(*(ULONG*)&in[16]);
+    ULONG myIP;
+    memcpy(&myIP, &in[16], sizeof(myIP));
+    myIP = ds.getMyIP(myIP);
    Log::getInstance()->log("MVPRelay", Log::DEBUG, "Sending my IP as %x", ntohl(myIP));

    // Required return parameters:
@@ -102,13 +106,13 @@
    memcpy(out, in, 4);

    // Return magic number is 0xfafebabe
-    *(ULONG*)&out[4] = htonl(0xfafebabe);
+    htoncpy(&out[4], 0xfafebabe);

    // Copy client IP and port to reply
    memcpy(&out[16], &in[16], 6);

    // Insert server address
-    *(ULONG*)&out[24] = myIP;
+    memcpy(&out[24], &myIP, sizeof(myIP));

    // Send it
    ds.send(ds.getFromIPA(), peerPort, (char*)out, 52);
Index: responsepacket.c
===================================================================
--- responsepacket.c (revision 7)
+++ responsepacket.c (working copy)
@@ -53,9 +53,9 @@
  buffer = (UCHAR*)malloc(bufSize);
  if (!buffer) return false;
 
-  *(ULONG*)&buffer[0] = htonl(1); // RR channel
-  *(ULONG*)&buffer[4] = htonl(requestID);
-  *(ULONG*)&buffer[userDataLenPos] = 0;
+  htoncpy(buffer, 1);  // RR channel
+  htoncpy(buffer+4, requestID);
+  htoncpy(buffer+userDataLenPos, 0);
  bufUsed = headerLength;

  return true;
@@ -63,7 +63,7 @@

void ResponsePacket::finalise()
{
-  *(ULONG*)&buffer[userDataLenPos] = htonl(bufUsed - headerLength);
+  htoncpy(buffer + userDataLenPos, bufUsed - headerLength);
  //Log::getInstance()->log("Client", Log::DEBUG, "RP finalise %lu", bufUsed - headerLength);
}

@@ -87,46 +87,41 @@
bool ResponsePacket::addULONG(ULONG ul)
{
  if (!checkExtend(sizeof(ULONG))) return false;
-  *(ULONG*)&buffer[bufUsed] = htonl(ul);
-  bufUsed += sizeof(ULONG);
+  bufUsed = htoncpy(buffer + bufUsed, ul) - buffer;
  return true;
}  

bool ResponsePacket::addUCHAR(UCHAR c)
{
  if (!checkExtend(sizeof(UCHAR))) return false;
-  buffer[bufUsed] = c;
-  bufUsed += sizeof(UCHAR);
+  buffer[bufUsed++] = c;
  return true;
}  
 
bool ResponsePacket::addLONG(LONG l)
{
  if (!checkExtend(sizeof(LONG))) return false;
-  *(LONG*)&buffer[bufUsed] = htonl(l);
-  bufUsed += sizeof(LONG);
+  bufUsed = htoncpy(buffer + bufUsed, l) - buffer;
  return true;
}

bool ResponsePacket::addULLONG(ULLONG ull)
{
  if (!checkExtend(sizeof(ULLONG))) return false;
-  *(ULLONG*)&buffer[bufUsed] = htonll(ull);
-  bufUsed += sizeof(ULLONG);
+  bufUsed = htoncpy(buffer + bufUsed, ull) - buffer;
  return true;
}

bool ResponsePacket::adddouble(double d)
{
-  if (!checkExtend(sizeof(double))) return false;
-  ULLONG ull;
-  memcpy(&ull,&d,sizeof(double));
-  *(ULLONG*)&buffer[bufUsed] = htonll(ull);
-  bufUsed += sizeof(ULLONG);
-  return true;
+  union {
+    double d;
+    ULLONG ull;
+  } u;
+  u.d = d;
+  return addULLONG(u.ull);
}

-
bool ResponsePacket::checkExtend(ULONG by)
{
  if ((bufUsed + by) < bufSize) return true;
@@ -138,23 +133,3 @@
  return true;
}

-ULLONG ResponsePacket::htonll(ULLONG a)
-{
-  #if BYTE_ORDER == BIG_ENDIAN
-    return a;
-  #else
-    ULLONG b = 0;
-
-    b = ((a << 56) & 0xFF00000000000000ULL)
-      | ((a << 40) & 0x00FF000000000000ULL)
-      | ((a << 24) & 0x0000FF0000000000ULL)
-      | ((a <<  8) & 0x000000FF00000000ULL)
-      | ((a >>  8) & 0x00000000FF000000ULL)
-      | ((a >> 24) & 0x0000000000FF0000ULL)
-      | ((a >> 40) & 0x000000000000FF00ULL)
-      | ((a >> 56) & 0x00000000000000FFULL) ;
-
-    return b;
-  #endif
-}
-
Index: responsepacket.h
===================================================================
--- responsepacket.h (revision 7)
+++ responsepacket.h (working copy)
@@ -49,8 +49,7 @@
    ULONG bufUsed;

    bool checkExtend(ULONG by);
-    ULLONG htonll(ULLONG a);
-    
+
    const static ULONG headerLength = 12;
    const static ULONG userDataLenPos = 8;
};
Index: serialize.c
===================================================================
--- serialize.c (revision 7)
+++ serialize.c (working copy)
@@ -97,28 +97,22 @@

int SerializeBuffer::encodeLong(ULONG data) {
  if (checkSpace( (int)sizeof(ULONG))!=0) return -1;
-  *((ULONG *)(current))=htonl(data);
-  current+=sizeof(ULONG);
+  current = htoncpy(current, data);
  return 0;
}
int SerializeBuffer::encodeShort(USHORT data) {
  if (checkSpace( (int)sizeof(USHORT))!=0) return -1;
-  *((USHORT *)(current))=htons(data);
-  current+=sizeof(USHORT);
+  current = htoncpy(current, data);
  return 0;
}
int SerializeBuffer::encodeByte(UCHAR data) {
  if (checkSpace( (int)sizeof(UCHAR))!=0) return -1;
-  *((UCHAR *)(current))=data;
-  current+=sizeof(UCHAR);
+  current = htoncpy(current, data);
  return 0;
}
int SerializeBuffer::encodeLongLong(ULLONG data) {
  if (checkSpace( (int)sizeof(ULLONG))!=0) return -1;
-  *((ULONG *)(current))=htonl((data>>32) & 0xffffffff);
-  current+=sizeof(ULONG);
-  *((ULONG *)(current))=htonl(data & 0xffffffff);
-  current+=sizeof(ULONG);
+  current = htoncpy(current, data);
  return 0;
}
//string: 4 len, string with 0
@@ -126,8 +120,7 @@
  if (checkSpace( (int)sizeof(ULONG))!=0) return -1;
  ULONG len=0;
  if (str) len=strlen(str)+1;
-  *((ULONG *)(current))=htonl(len);
-  current+=sizeof(ULONG);
+  current = htoncpy(current, len);
  if (len == 0) return 0;
  if (checkSpace((int)len)!=0) return -1;
  strcpy((char *) current,str);
@@ -136,35 +129,27 @@
}
int SerializeBuffer::decodeLong( int &data) {
  if (checkSpace( (int)sizeof(ULONG))!=0) return -1;
-  data=(int)ntohl(*((ULONG *)(current)));
-  current+=sizeof(ULONG);
+  current = ntohcpy(data, current);
  return 0;
}
int SerializeBuffer::decodeLong(ULONG &data) {
  if (checkSpace( (int)sizeof(ULONG))!=0) return -1;
-  data=ntohl(*((ULONG *)(current)));
-  current+=sizeof(ULONG);
+  current = ntohcpy(data, current);
  return 0;
}
int SerializeBuffer::decodeShort(USHORT &data) {
  if (checkSpace( (int)sizeof(USHORT))!=0) return -1;
-  data=ntohs(*((USHORT *)(current)));
-  current+=sizeof(USHORT);
+  current = ntohcpy(data, current);
  return 0;
}
int SerializeBuffer::decodeByte(UCHAR &data) {
  if (checkSpace( (int)sizeof(UCHAR))!=0) return -1;
-  data=*((UCHAR *)current);
-  current+=sizeof(UCHAR);
+  current = ntohcpy(data, current);
  return 0;
}
int SerializeBuffer::decodeLongLong(ULLONG &data) {
  if (checkSpace( (int)sizeof(ULLONG))!=0) return -1;
-  ULLONG hd=ntohl(*((ULONG *)(current)));
-  current+=sizeof(ULONG);
-  ULLONG ld=ntohl(*((ULONG *)(current)));
-  current+=sizeof(ULONG);
-  data=(hd << 32) | ld;
+  current = ntohcpy(data, current);
  return 0;
}
//string: 4 len, string with 0
@@ -172,8 +157,7 @@
  strbuf=NULL;
  len=0;
  if (checkSpace( (int)sizeof(ULONG))!=0) return -1;
-  len=ntohl(*((ULONG *)(current)));
-  current+=sizeof(ULONG);
+  current = ntohcpy(len, current);
  if (len == 0) return 0;
  if (checkSpace((int)len)!=0) return -1;
  strbuf=new char[len];
Index: tftpclient.c
===================================================================
--- tftpclient.c (revision 7)
+++ tftpclient.c (working copy)
@@ -156,8 +156,8 @@
//  dump(data, (USHORT)length);

  if ((UINT)length < sizeof(USHORT)) return 0;
-  USHORT opcode = ntohs(*(USHORT*)data);
-  data += sizeof(USHORT);
+  USHORT opcode;
+  data = ntohcpy(opcode, data);
  length -= sizeof(USHORT);

  switch(opcode)
@@ -232,7 +232,8 @@

  if (length != 2) return 0;

-  USHORT ackBlock = ntohs(*(USHORT*)data);
+  USHORT ackBlock;
+  ntohcpy(ackBlock, data);

  if (ackBlock == (blockNumber - 1))
  {
@@ -290,8 +291,8 @@

int TftpClient::sendBlock()
{
-  *(USHORT*)&buffer[0] = htons(3);
-  *(USHORT*)&buffer[2] = htons(blockNumber++);
+  htoncpy<USHORT>(&buffer[0], 3);
+  htoncpy<USHORT>(&buffer[2], blockNumber++);
  bufferLength = 4 + fread(&buffer[4], 1, 512, file);

  if (bufferLength < 516) // 512 + 4 header
Index: vompclient.c
===================================================================
--- vompclient.c (revision 7)
+++ vompclient.c (working copy)
@@ -289,10 +289,10 @@

      log->log("Client", Log::DEBUG, "Received chan=%lu kats=%lu", channelID, kaTimeStamp);    

-      UCHAR buffer[8];
-      *(ULONG*)&buffer[0] = htonl(3); // KA CHANNEL
-      *(ULONG*)&buffer[4] = htonl(kaTimeStamp);
-      if (!tcp.sendPacket(buffer, 8))
+      ULONG buffer[2];
+      buffer[0] = htonl(3); // KA CHANNEL
+      buffer[1] = htonl(kaTimeStamp);
+      if (!tcp.sendPacket((UCHAR*)buffer, 8))
      {
        log->log("Client", Log::ERR, "Could not send back KA reply");
        break;
@@ -328,31 +328,6 @@
  }
}

-ULLONG VompClient::ntohll(ULLONG a)
-{
-  return htonll(a);
-}
-
-ULLONG VompClient::htonll(ULLONG a)
-{
-  #if BYTE_ORDER == BIG_ENDIAN
-    return a;
-  #else
-    ULLONG b = 0;
-
-    b = ((a << 56) & 0xFF00000000000000ULL)
-      | ((a << 40) & 0x00FF000000000000ULL)
-      | ((a << 24) & 0x0000FF0000000000ULL)
-      | ((a <<  8) & 0x000000FF00000000ULL)
-      | ((a >>  8) & 0x00000000FF000000ULL)
-      | ((a >> 24) & 0x0000000000FF0000ULL)
-      | ((a >> 40) & 0x000000000000FF00ULL)
-      | ((a >> 56) & 0x00000000000000FFULL) ;
-
-    return b;
-  #endif
-}
-
#ifndef VOMPSTANDALONE

cChannel* VompClient::channelFromNumber(ULONG channelNumber)
Index: vompclient.h
===================================================================
--- vompclient.h (revision 7)
+++ vompclient.h (working copy)
@@ -81,9 +81,6 @@
    static void incClients();
    static void decClients();

-    static ULLONG ntohll(ULLONG a);
-    static ULLONG htonll(ULLONG a);
-    
    VompClientRRProc rrproc;
    pthread_t runThread;
    int initted;
Index: vompclientrrproc.c
===================================================================
--- vompclientrrproc.c (revision 7)
+++ vompclientrrproc.c (working copy)
@@ -952,7 +952,8 @@

int VompClientRRProc::processGetChannelPids()
{
-  ULONG channelNumber = ntohl(*(ULONG*)req->data);
+  ULONG channelNumber;
+  ntohcpy(channelNumber, req->data);

  cChannel* channel = x.channelFromNumber(channelNumber);
  if (!channel)
@@ -1076,7 +1077,8 @@
  }
 
  log->log("RRProc", Log::DEBUG, "req->dataLength = %i", req->dataLength);
-  ULONG channelNumber = ntohl(*(ULONG*)req->data);
+  ULONG channelNumber;
+  ntohcpy(channelNumber, req->data);

  cChannel* channel = x.channelFromNumber(channelNumber);

@@ -1172,9 +1174,10 @@

  UCHAR* data = req->data;

-  ULLONG position = x.ntohll(*(ULLONG*)data);
-  data += sizeof(ULLONG);
-  ULONG amount = ntohl(*(ULONG*)data);
+  ULLONG position;
+  data = ntohcpy(position, data);
+  ULONG amount;
+  ntohcpy(amount, data);

  log->log("RRProc", Log::DEBUG, "getblock pos = %llu length = %lu", position, amount);

@@ -1239,7 +1242,8 @@
{
  ULLONG retval = 0;

-  ULONG frameNumber = ntohl(*(ULONG*)req->data);
+  ULONG frameNumber;
+  ntohcpy(frameNumber, req->data);

  if (!x.recplayer)
  {
@@ -1262,7 +1266,8 @@
{
  ULONG retval = 0;

-  ULLONG position = x.ntohll(*(ULLONG*)req->data);
+  ULLONG position;
+  ntohcpy(position, req->data);

  if (!x.recplayer)
  {
@@ -1285,11 +1290,12 @@
{
  bool success = false;

-  ULONG* data = (ULONG*)req->data;
+  UCHAR* data = req->data;

-  ULONG frameNumber = ntohl(*data);
-  data++;
-  ULONG direction = ntohl(*data);
+  ULONG frameNumber;
+  data = ntohcpy(frameNumber, data);
+  ULONG direction;
+  ntohcpy(direction, data);

  ULLONG rfilePosition = 0;
  ULONG rframeNumber = 0;
@@ -1326,14 +1332,17 @@

int VompClientRRProc::processGetChannelSchedule()
{
-  ULONG* data = (ULONG*)req->data;
+  UCHAR* data = req->data;

-  ULONG channelNumber = ntohl(*data);
-  data++;
-  ULONG startTime = ntohl(*data);
-  data++;
-  ULONG duration = ntohl(*data);
+  ULONG channelNumber;
+  data = ntohcpy(channelNumber, data);

+  ULONG startTime;
+  data = ntohcpy(startTime, data);
+
+  ULONG duration;
+  ntohcpy(duration, data);
+
  log->log("RRProc", Log::DEBUG, "get schedule called for channel %lu", channelNumber);

  cChannel* channel = x.channelFromNumber(channelNumber);
@@ -1570,13 +1579,22 @@
  log->log("RRProc", Log::DEBUG, "Delete timer called");
  // get timer
 
-  int position = 0;
+  UCHAR* data = req->data;
 
-  INT delChannel = ntohl(*(ULONG*)&req->data[position]); position += 4;
-  INT delWeekdays = ntohl(*(ULONG*)&req->data[position]); position += 4;
-  INT delDay = ntohl(*(ULONG*)&req->data[position]); position += 4;  
-  INT delStart = ntohl(*(ULONG*)&req->data[position]); position += 4;  
-  INT delStop = ntohl(*(ULONG*)&req->data[position]); position += 4;
+  INT delChannel;
+  data = ntohcpy(delChannel, data);
+
+  INT delWeekdays;
+  data = ntohcpy(delWeekdays, data);
+
+  INT delDay;
+  data = ntohcpy(delDay, data);
+
+  INT delStart;
+  data = ntohcpy(delStart, data);
+
+  INT delStop;
+  data = ntohcpy(delStop, data);
   
  cTimer* ti = NULL;
  for (ti = Timers.First(); ti; ti = Timers.Next(ti))
#3
Quote from: AndersF on December 03, 2009, 20:11:38
Patch below:

anders@server1:/mnt/disk1/src/vdr-1.6.0/PLUGINS/src$ cat vompserver.patch
diff -Naur vompserver.org/responsepacket.c vompserver/responsepacket.c
--- vompserver.org/responsepacket.c   2009-11-20 05:34:28.075696779 +0000
+++ vompserver/responsepacket.c   2009-11-22 06:32:37.415696613 +0000
@@ -87,7 +87,8 @@
bool ResponsePacket::addULONG(ULONG ul)
{
   if (!checkExtend(sizeof(ULONG))) return false;
-  *(ULONG*)&buffer[bufUsed] = htonl(ul);
+  ULONG ulnw = htonl(ul);
+  memcpy(buffer + bufUsed, &ulnw, sizeof(ULONG));
   bufUsed += sizeof(ULONG);
   return true;

@@ -103,7 +104,8 @@
bool ResponsePacket::addLONG(LONG l)
{
   if (!checkExtend(sizeof(LONG))) return false;
-  *(LONG*)&buffer[bufUsed] = htonl(l);
+  LONG lnw = htonl(l);
+  memcpy(buffer + bufUsed, &lnw, sizeof(LONG));
   bufUsed += sizeof(LONG);
   return true;
}
@@ -111,7 +113,8 @@
bool ResponsePacket::addULLONG(ULLONG ull)
{
   if (!checkExtend(sizeof(ULLONG))) return false;
-  *(ULLONG*)&buffer[bufUsed] = htonll(ull);
+  ULLONG ullnw = htonll(ull);
+  memcpy(buffer + bufUsed, &ullnw, sizeof(ULLONG));
   bufUsed += sizeof(ULLONG);
   return true;
}


Ist this the complete patch? It did not work for me. Actually I have seen this dubious type punning pointer pattern all over the code. There must be a lot more places where this is a problem.