Modify the packet size in transport protocol. 85/100485/7
authorKim Gunsoo <gunsoo83.kim@samsung.com>
Wed, 9 Dec 2015 04:59:27 +0000 (13:59 +0900)
committershingil.kang <shingil.kang@samsung.com>
Fri, 9 Dec 2016 05:36:08 +0000 (14:36 +0900)
- increase the transport packet size. (4KB -> 256KB)
- read USB transport packet as 4KB block repeatedly

Change-Id: I949ff050e51b907523922104bd5683b1132f2b2c
Signed-off-by: Kim Gunsoo <gunsoo83.kim@samsung.com>
src/sdb.c
src/sdb.h
src/sockets.c
src/transport.c
src/transport_local.c
src/transport_usb.c
src/usb_linux_client.c
src/utils.h

index ac7f573..017bfb0 100644 (file)
--- a/src/sdb.c
+++ b/src/sdb.c
@@ -543,7 +543,7 @@ static void send_connect(atransport *t)
     cp->msg.command = A_CNXN;
     cp->msg.arg0 = A_VERSION;
 #ifdef SUPPORT_ENCRYPT
-       cp->msg.arg1 = MAX_PAYLOAD - 100; // connection 시, sdb server의 패킷 크기를 암호화 오버로드 만큼 줄임
+   cp->msg.arg1 = MAX_PAYLOAD - 100; // connection 시, sdb server의 패킷 크기를 암호화 오버로드 만큼 줄임
 #else
     cp->msg.arg1 = MAX_PAYLOAD;
 #endif
@@ -794,6 +794,18 @@ void parse_banner(char *banner, atransport *t)
     t->connection_state = CS_HOST;
 }
 
+static void update_version(atransport *t, int version, size_t payload)
+{
+#ifdef SUPPORT_ENCRYPT
+    size_t max_payload = MAX_PAYLOAD - 100;
+#else
+    size_t max_payload = MAX_PAYLOAD;
+#endif
+    t->protocol_version = min(version, A_VERSION);
+    t->max_payload = min(payload, max_payload);
+    D("update transport version. version=%x, max_payload=%d\n", t->protocol_version, t->max_payload);
+}
+
 void handle_packet(apacket *p, atransport *t)
 {
     // Verify pointer p
@@ -829,6 +841,7 @@ void handle_packet(apacket *p, atransport *t)
             t->connection_state = CS_OFFLINE;
             handle_offline(t);
         }
+        update_version(t, p->msg.arg0, p->msg.arg1);
         parse_banner((char*) p->data, t);
         handle_online();
         if(!HOST) send_connect(t);
index 348a7eb..226da64 100644 (file)
--- a/src/sdb.h
+++ b/src/sdb.h
@@ -28,7 +28,9 @@
 #endif
 #include <tzplatform_config.h>
 
-#define MAX_PAYLOAD 4096
+#define MAX_PAYLOAD_V1  (4*1024)
+#define MAX_PAYLOAD_V2  (256*1024)
+#define MAX_PAYLOAD     MAX_PAYLOAD_V2
 
 #define A_SYNC 0x434e5953
 #define A_CNXN 0x4e584e43
@@ -212,6 +214,8 @@ struct atransport
         /* a list of adisconnect callbacks called when the transport is kicked */
     int          kicked;
     adisconnect  disconnects;
+    int protocol_version;
+    size_t max_payload;
 
 #ifdef SUPPORT_ENCRYPT
        unsigned encryption; // 해당 연결이 암호화 모드인지 확인하는 flag , 0 = no-encryption / 1 = encryption
@@ -308,6 +312,7 @@ asocket *create_local_service_socket(const char *destination);
 asocket *create_remote_socket(unsigned id, atransport *t);
 void connect_to_remote(asocket *s, const char *destination);
 void connect_to_smartsocket(asocket *s);
+size_t asock_get_max_payload(asocket *s);
 
 void fatal(const char *fmt, ...);
 void fatal_errno(const char *fmt, ...);
@@ -428,7 +433,7 @@ int get_emulator_guestip(char str[], int str_size);
 apacket *get_apacket(void);
 void put_apacket(apacket *p);
 
-int check_header(apacket *p);
+int check_header(apacket *p, atransport *t);
 int check_data(apacket *p);
 
 #if !TRACE_PACKETS
index 801ff42..71d646d 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "sdb.h"
 #include "strutils.h"
+#include "utils.h"
 
 SDB_MUTEX_DEFINE( socket_list_lock );
 
@@ -322,10 +323,11 @@ static void local_socket_event_func(int fd, unsigned ev, void *_s)
                // sdb server에서 패킷 데이터의 크기를 MAX_PAYLOAD-100보다 작은 지를 체크함.
                // sdbd에서 패킷 데이터를 MAX_PAYLOAD - 200로 잡아서 암호화 하게되면 
                // 최대 MAX_PAYLOAD - 100 크기의 패킷을 생성하게 됨.
-               const size_t max_payload = MAX_PAYLOAD - 200; 
+               const size_t max_payload = asock_get_max_payload(s) - 200;
         size_t avail = max_payload;
 #else
-               size_t avail = MAX_PAYLOAD;
+        const size_t max_payload = asock_get_max_payload(s);
+               size_t avail = max_payload;
 #endif
 
         int r = 0;
@@ -350,6 +352,7 @@ static void local_socket_event_func(int fd, unsigned ev, void *_s)
         }
         D("LS(%d): fd=%d post avail loop. r=%d is_eof=%d forced_eof=%d\n",
           s->id, s->fd, r, is_eof, s->fde.force_eof);
+
 #ifdef SUPPORT_ENCRYPT
        //변경된 최대 패킷 크기로 코드 수정
         if((avail == max_payload) || (s->peer == 0)) {
@@ -357,10 +360,10 @@ static void local_socket_event_func(int fd, unsigned ev, void *_s)
         } else {
             p->len = max_payload - avail;
 #else
-        if((avail == MAX_PAYLOAD) || (s->peer == 0)) {
+        if((avail == max_payload) || (s->peer == 0)) {
             put_apacket(p);
         } else {
-            p->len = MAX_PAYLOAD - avail;
+            p->len = max_payload - avail;
 #endif
             r = s->peer->enqueue(s->peer, p);
             D("LS(%d): fd=%d post peer->enqueue(). r=%d\n", s->id, s->fd, r);
@@ -549,9 +552,9 @@ void connect_to_remote(asocket *s, const char *destination)
 {
     D("Connect_to_remote call RS(%d) fd=%d\n", s->id, s->fd);
     apacket *p = get_apacket();
-    int len = strlen(destination) + 1;
+    size_t len = strlen(destination) + 1;
 
-    if(len > (MAX_PAYLOAD-1)) {
+    if(len > (asock_get_max_payload(s)-1)) {
         fatal("destination oversized");
     }
 
@@ -656,7 +659,7 @@ static int smart_socket_enqueue(asocket *s, apacket *p)
         s->pkt_first = p;
         s->pkt_last = p;
     } else {
-        if((s->pkt_first->len + p->len) > MAX_PAYLOAD) {
+        if((s->pkt_first->len + p->len) > asock_get_max_payload(s)) {
             D("SS(%d): overflow\n", s->id);
             put_apacket(p);
             goto fail;
@@ -860,3 +863,15 @@ void connect_to_smartsocket(asocket *s)
     ss->peer = s;
     s->ready(s);
 }
+
+size_t asock_get_max_payload(asocket *s)
+{
+    size_t max_payload = MAX_PAYLOAD;
+    if (s->transport) {
+        max_payload = min(max_payload, s->transport->max_payload);
+    }
+    if (s->peer && s->peer->transport) {
+        max_payload = min(max_payload, s->peer->transport->max_payload);
+    }
+    return max_payload;
+}
index 470e55f..616acab 100644 (file)
@@ -653,6 +653,9 @@ static void transport_registration_func(int _fd, unsigned ev, void *data)
         return;
     }
 
+    t->protocol_version = A_VERSION;
+    t->max_payload = MAX_PAYLOAD;
+
     /* don't create transport threads for inaccessible devices */
     if (t->connection_state != CS_NOPERM) {
         /* initial references are the two threads */
@@ -1187,15 +1190,15 @@ int writex(int fd, const void *ptr, size_t len)
     return 0;
 }
 
-int check_header(apacket *p)
+int check_header(apacket *p, atransport *t)
 {
     if(p->msg.magic != (p->msg.command ^ 0xffffffff)) {
         D("check_header(): invalid magic\n");
         return -1;
     }
 
-    if(p->msg.data_length > MAX_PAYLOAD) {
-        D("check_header(): %d > MAX_PAYLOAD\n", p->msg.data_length);
+    if(p->msg.data_length > t->max_payload) {
+        D("check_header(): %d > transport->max_payload(%d)\n", p->msg.data_length, t->max_payload);
         return -1;
     }
 
index a6adb0b..dd145bd 100644 (file)
@@ -87,7 +87,7 @@ static int remote_read(apacket *p, atransport *t)
     D("read remote packet: %04x arg0=%0x arg1=%0x data_length=%0x data_check=%0x magic=%0x\n",
       p->msg.command, p->msg.arg0, p->msg.arg1, p->msg.data_length, p->msg.data_check, p->msg.magic);
 #endif
-    if(check_header(p)) {
+    if(check_header(p, t)) {
         D("bad header: terminated (data)\n");
         return -1;
     }
index 932e170..96905bf 100644 (file)
@@ -57,7 +57,7 @@ static int remote_read(apacket *p, atransport *t)
 
     fix_endians(p);
 
-    if(check_header(p)) {
+    if(check_header(p, t)) {
         D("remote usb: check_header failed\n");
         return -1;
     }
index 5d722b4..efeff2c 100644 (file)
@@ -98,17 +98,25 @@ int linux_usb_write(usb_handle *h, const void *data, int len)
 
 int linux_usb_read(usb_handle *h, void *data, size_t len)
 {
-    int n;
-
-    D("about to read (fd=%d, len=%d)\n", h->fd, len);
-    n = sdb_read(h->fd, data, len);
-    if(n != len) {
-        D("ERROR: fd = %d, n = %d, errno = %d\n",
-            h->fd, n, errno);
-        return -1;
-    }
-    D("[ done fd=%d ]\n", h->fd);
-    return 0;
+      D("about to read (fd=%d, len=%d)\n", h->fd, len);
+        while (len > 0) {
+            /* The sdb_read does not support read larger than 4096 bytes at once.
+               Read 4096 byte block repeatedly when reading data is larger than 4096 bytes. */
+            int bytes_to_read = len < 4096 ? len : 4096;
+            int n = sdb_read(h->fd, data, bytes_to_read);
+            if(n < 0) {
+                if(errno == EINTR) {
+                    continue;
+                } else {
+                    D("ERROR: fd = %d, n = %d, errno = %d\n", h->fd, n, errno);
+                    return -1;
+                }
+            }
+            len -= n;
+            data = ((char*) data) + n;
+        }
+        D("[ done fd=%d ]\n", h->fd);
+        return 0;
 }
 
 void linux_usb_init()
index 7e78b6e..a2d0243 100644 (file)
@@ -80,5 +80,13 @@ char** str_split(char* a_str, const char a_delim);
 #define SDB_KEEPALIVE_IDLE  (1)
 #define SDB_KEEPALIVE_INTVL (1)
 int keep_alive(int fd, int onoff, int cnt, int idle, int interval);
+#define min(a,b)            \
+({ __typeof__ (a) _a = (a); \
+__typeof__ (b) _b = (b);    \
+_a > _b ? _b : _a; })
+#define max(a,b)            \
+({ __typeof__ (a) _a = (a); \
+__typeof__ (b) _b = (b);    \
+_a > _b ? _a : _b; })
 
 #endif /* _SDB_UTILS_H */