SEL Verification - bug fixed
authorSung-jae Park <nicesj.park@samsung.com>
Sat, 28 Jul 2012 11:40:06 +0000 (20:40 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Sat, 28 Jul 2012 23:46:42 +0000 (08:46 +0900)
Remove the FIOREAD.
Handling the receive ZERO byte receiving

S1-6489
S1-6520
S1-6337
S1-6494
S1-5750
P120725-0076

Change-Id: Iaf8efdd8836b3ca60f0ca7cdcf65c3457e7f3a36

debian/changelog
include/com-core.h
include/com-core_packet.h
include/packet.h
include/secure_socket.h
packaging/libcom-core.spec
src/com-core.c
src/com-core_packet.c
src/packet.c
src/secure_socket.c

index ec46664..64499e2 100644 (file)
@@ -1,3 +1,10 @@
+com-core (0.2.0) unstable; urgency=low
+
+  * Git: slp/pkgs/c/com-core
+  * Tag: com-core_0.2.0
+
+ -- Sung-jae Park <nicesj.park@samsung.com>  Sun, 29 Jul 2012 08:46:23 +0900
+
 com-core (0.1.1) unstable; urgency=low
 
   * Git: slp/pkgs/c/com-core
index d87c55b..3c661fb 100644 (file)
@@ -7,14 +7,20 @@ enum com_core_event_type {
        CONNECTOR_DISCONNECTED,
 };
 
-extern int com_core_server_create(const char *addr, int is_sync, int (*service_cb)(int fd, int readsize, void *data), void *data);
-extern int com_core_client_create(const char *addr, int is_sync, int (*service_cb)(int fd, int readsize, void *data), void *data);
+extern int com_core_server_create(const char *addr, int is_sync, int (*service_cb)(int fd, void *data), void *data);
+extern int com_core_client_create(const char *addr, int is_sync, int (*service_cb)(int fd, void *data), void *data);
 extern int com_core_server_destroy(int handle);
 extern int com_core_client_destroy(int handle);
 
 extern int com_core_add_event_callback(enum com_core_event_type type, int (*service_cb)(int handle, void *data), void *data);
 extern void *com_core_del_event_callback(enum com_core_event_type type, int (*service_cb)(int handle, void *data), void *data);
 
+/*!
+ * \brief If the connection is lost, this recv function will call the disconnected callback.
+ */
+extern int com_core_recv(int handle, char *buffer, int size, int *sender_pid, double timeout);
+extern int com_core_send(int handle, const char *buffer, int size, double timeout);
+
 #ifdef __cplusplus
 }
 #endif
index 280e5ce..3a1e155 100644 (file)
@@ -7,10 +7,9 @@ struct method {
        struct packet *(*handler)(pid_t pid, int handle, const struct packet *packet);
 };
 
-extern int com_core_packet_async_send(int handle, struct packet *packet, unsigned int timeout, int (*recv_cb)(pid_t, int handle, const struct packet *packet, void *data), void *data);
+extern int com_core_packet_async_send(int handle, struct packet *packet, double timeout, int (*recv_cb)(pid_t pid, int handle, const struct packet *packet, void *data), void *data);
 extern int com_core_packet_send_only(int handle, struct packet *packet);
-extern struct packet *com_core_packet_oneshot_send(const char *addr, struct packet *packet);
-
+extern struct packet *com_core_packet_oneshot_send(const char *addr, struct packet *packet, double timeout);
 extern int com_core_packet_client_init(const char *addr, int is_sync, struct method *table);
 extern int com_core_packet_client_fini(int handle);
 extern int com_core_packet_server_init(const char *addr, struct method *table);
index 5fbb436..fd15eb8 100644 (file)
@@ -23,7 +23,7 @@ extern struct packet *packet_ref(struct packet *packet);
 extern struct packet *packet_unref(struct packet *packet);
 
 extern const void * const packet_data(const struct packet *packet);
-extern const unsigned long const packet_seq(const struct packet *packet);
+extern const double const packet_seq(const struct packet *packet);
 extern const enum packet_type const packet_type(const struct packet *packet);
 extern const int const packet_version(const struct packet *packet);
 extern const int const packet_payload_size(const struct packet *packet);
index 70d2485..088d795 100644 (file)
@@ -38,7 +38,6 @@ extern int secure_socket_create_server(const char *peer);
  * Get the raw handle to use it for non-blocking mode.
  */
 extern int secure_socket_get_connection_handle(int server_handle);
-extern int secure_socket_remove_connection_handle(int conn_handle);
 
 /*
  * Send data to the connected peer.
@@ -53,7 +52,7 @@ extern int secure_socket_recv(int conn, char *buffer, int size, int *sender_pid)
 /*
  * Destroy a connection
  */
-extern int secure_socket_destroy(int conn);
+extern int secure_socket_destroy_handle(int conn);
 
 #ifdef __cplusplus
 }
index 7f89265..3324b69 100644 (file)
@@ -1,6 +1,6 @@
 Name: libcom-core
 Summary: Library for the light-weight IPC 
-Version: 0.1.1
+Version: 0.2.0
 Release: 1
 Group: main/util
 License: Samsung Proprietary License
index a4fae74..e081974 100644 (file)
@@ -4,7 +4,8 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <stdlib.h>
-#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
 
 #include <glib.h>
 
@@ -26,7 +27,7 @@ static struct {
 };
 
 struct cbdata {
-       int (*service_cb)(int fd, int readsize, void *data);
+       int (*service_cb)(int fd, void *data);
        void *data;
 };
 
@@ -68,36 +69,28 @@ static gboolean client_cb(GIOChannel *src, GIOCondition cond, gpointer data)
        int client_fd;
        struct cbdata *cbdata = data;
        int ret;
-       int readsize;
 
        client_fd = g_io_channel_unix_get_fd(src);
 
        if (!(cond & G_IO_IN)) {
                DbgPrint("Client is disconencted\n");
                invoke_disconn_cb_list(client_fd);
-               secure_socket_remove_connection_handle(client_fd);
+               secure_socket_destroy_handle(client_fd);
                return FALSE;
        }
 
        if ((cond & G_IO_ERR) || (cond & G_IO_HUP) || (cond & G_IO_NVAL)) {
                DbgPrint("Client connection is lost\n");
                invoke_disconn_cb_list(client_fd);
-               secure_socket_remove_connection_handle(client_fd);
-               return FALSE;
-       }
-
-       if (ioctl(client_fd, FIONREAD, &readsize) < 0 || readsize == 0) {
-               DbgPrint("Client is disconencted (fd: %d, readsize: %d)\n", client_fd, readsize);
-               invoke_disconn_cb_list(client_fd);
-               secure_socket_remove_connection_handle(client_fd);
+               secure_socket_destroy_handle(client_fd);
                return FALSE;
        }
 
-       ret = cbdata->service_cb(client_fd, readsize, cbdata->data);
+       ret = cbdata->service_cb(client_fd, cbdata->data);
        if (ret < 0) {
-               DbgPrint("service callback returns < 0\n");
+               DbgPrint("service callback returns %d < 0\n", ret);
                invoke_disconn_cb_list(client_fd);
-               secure_socket_remove_connection_handle(client_fd);
+               secure_socket_destroy_handle(client_fd);
                return FALSE;
        }
 
@@ -145,7 +138,7 @@ static gboolean accept_cb(GIOChannel *src, GIOCondition cond, gpointer cbdata)
        gio = g_io_channel_unix_new(client_fd);
        if (!gio) {
                ErrPrint("Failed to get gio\n");
-               secure_socket_remove_connection_handle(client_fd);
+               secure_socket_destroy_handle(client_fd);
                free(cbdata);
                return FALSE;
        }
@@ -162,7 +155,7 @@ static gboolean accept_cb(GIOChannel *src, GIOCondition cond, gpointer cbdata)
                        g_error_free(err);
                }
                g_io_channel_unref(gio);
-               secure_socket_remove_connection_handle(client_fd);
+               secure_socket_destroy_handle(client_fd);
                free(cbdata);
                return FALSE;
        }
@@ -174,7 +167,7 @@ static gboolean accept_cb(GIOChannel *src, GIOCondition cond, gpointer cbdata)
        return TRUE;
 }
 
-EAPI int com_core_server_create(const char *addr, int is_sync, int (*service_cb)(int fd, int readsize, void *data), void *data)
+EAPI int com_core_server_create(const char *addr, int is_sync, int (*service_cb)(int fd, void *data), void *data)
 {
        GIOChannel *gio;
        guint id;
@@ -234,7 +227,7 @@ EAPI int com_core_server_create(const char *addr, int is_sync, int (*service_cb)
        return fd;
 }
 
-EAPI int com_core_client_create(const char *addr, int is_sync, int (*service_cb)(int fd, int readsize, void *data), void *data)
+EAPI int com_core_client_create(const char *addr, int is_sync, int (*service_cb)(int fd, void *data), void *data)
 {
        GIOChannel *gio;
        guint id;
@@ -313,6 +306,112 @@ EAPI int com_core_add_event_callback(enum com_core_event_type type, int (*evt_cb
        return 0;
 }
 
+EAPI int com_core_recv(int handle, char *buffer, int size, int *sender_pid, double timeout)
+{
+       int readsize;
+       int ret;
+
+       readsize = 0;
+       while (size > 0) {
+               if (timeout > 0.0f) {
+                       struct timeval tv;
+                       fd_set set;
+
+                       FD_ZERO(&set);
+                       FD_SET(handle, &set);
+
+                       tv.tv_sec = (unsigned long)timeout;
+                       tv.tv_usec = (timeout - (unsigned long)timeout) * 1000000u;
+
+                       ret = select(handle + 1, &set, NULL, NULL, &tv);
+                       if (ret < 0) {
+                               /*!< Error */
+                               ret = -errno;
+                               ErrPrint("Error: %s\n", strerror(errno));
+                               return ret;
+                       } else if (ret == 0) {
+                               /*!< Timeout */
+                               ErrPrint("Timeout expired\n");
+                               return -ETIMEDOUT;
+                       }
+
+                       if (!FD_ISSET(handle, &set)) {
+                               ErrPrint("Unexpected handle is toggled\n");
+                               return -EINVAL;
+                       }
+               }
+
+               ret = secure_socket_recv(handle, buffer + readsize, size, sender_pid);
+               if (ret < 0) {
+                       if (ret == -EAGAIN) {
+                               DbgPrint("Retry to get data (%d:%d)\n", readsize, size);
+                               continue;
+                       }
+                       return ret;
+               } else if (ret == 0) {
+                       return 0;
+               }
+
+               size -= ret;
+               readsize += ret;
+       }
+
+       return readsize;
+}
+
+EAPI int com_core_send(int handle, const char *buffer, int size, double timeout)
+{
+       int writesize;
+       int ret;
+
+       writesize = 0;
+       while (size > 0) {
+               if (timeout > 0.0f) {
+                       struct timeval tv;
+                       fd_set set;
+
+                       FD_ZERO(&set);
+                       FD_SET(handle, &set);
+
+                       tv.tv_sec = (unsigned long)timeout;
+                       tv.tv_usec = (timeout - (unsigned long)timeout) * 1000000u;
+
+                       ret = select(handle + 1, NULL, &set, NULL, &tv);
+                       if (ret < 0) {
+                               ret = -errno;
+                               ErrPrint("Error: %s\n", strerror(errno));
+                               return ret;
+                       } else if (ret == 0) {
+                               ErrPrint("Timeout expired\n");
+                               return -ETIMEDOUT;
+                       }
+
+                       if (!FD_ISSET(handle, &set)) {
+                               ErrPrint("Unexpected handle is toggled\n");
+                               return -EINVAL;
+                       }
+               }
+
+               ret = secure_socket_send(handle, buffer + writesize, size);
+               if (ret < 0) {
+                       if (ret == -EAGAIN) {
+                               DbgPrint("Retry to send data (%d:%d)\n", writesize, size);
+                               continue;
+                       }
+                       DbgPrint("Failed to send: %d\n", ret);
+                       return ret;
+               } else if (ret == 0) {
+                       DbgPrint("Disconnected? : Send bytes: 0\n");
+                       return 0;
+               }
+
+               size -= ret;
+               writesize += ret;
+       }
+
+       return writesize;
+}
+
 EAPI void *com_core_del_event_callback(enum com_core_event_type type, int (*cb)(int handle, void *data), void *data)
 {
        struct dlist *l;
@@ -346,15 +445,15 @@ EAPI void *com_core_del_event_callback(enum com_core_event_type type, int (*cb)(
 
 EAPI int com_core_server_destroy(int handle)
 {
-       if (close(handle) < 0)
-               ErrPrint("Close error[%d]: %s\n", handle, strerror(errno));
+       DbgPrint("Close server handle[%d]\n", handle);
+       secure_socket_destroy_handle(handle);
        return 0;
 }
 
 EAPI int com_core_client_destroy(int handle)
 {
-       if (close(handle) < 0)
-               ErrPrint("Close error[%d]: %s\n", handle, strerror(errno));
+       DbgPrint("Close client handle[%d]\n", handle);
+       secure_socket_destroy_handle(handle);
        return 0;
 }
 
index 69d5b1e..3efab24 100644 (file)
@@ -6,7 +6,6 @@
 #include <fcntl.h>
 #include <sys/time.h>
 #include <sys/types.h>
-#include <sys/ioctl.h>
 
 #include <glib.h>
 #include <dlog.h>
@@ -19,7 +18,7 @@
 #include "com-core_packet.h"
 #include "util.h"
 
-#define DEFAULT_TIMEOUT 2
+#define DEFAULT_TIMEOUT 2.0f
 
 static struct info {
        struct dlist *recv_list;
@@ -38,8 +37,6 @@ struct request_ctx {
        struct packet *packet;
        int (*recv_cb)(pid_t pid, int handle, const struct packet *packet, void *data);
        void *data;
-
-       guint timeout;
 };
 
 struct recv_ctx {
@@ -53,9 +50,10 @@ struct recv_ctx {
        int offset;
        pid_t pid;
        struct packet *packet;
+       double timeout;
 };
 
-static inline struct request_ctx *find_request_ctx(int handle, unsigned long seq)
+static inline struct request_ctx *find_request_ctx(int handle, double seq)
 {
        struct request_ctx *ctx;
        struct dlist *l;
@@ -71,9 +69,6 @@ static inline struct request_ctx *find_request_ctx(int handle, unsigned long seq
 
 static inline void destroy_request_ctx(struct request_ctx *ctx)
 {
-       if (ctx->timeout > 0)
-               g_source_remove(ctx->timeout);
-
        packet_unref(ctx->packet);
        dlist_remove_data(s_info.request_list, ctx);
        free(ctx);
@@ -119,7 +114,7 @@ static inline void destroy_recv_ctx(struct recv_ctx *ctx)
        free(ctx);
 }
 
-static inline struct recv_ctx *create_recv_ctx(int handle)
+static inline struct recv_ctx *create_recv_ctx(int handle, double timeout)
 {
        struct recv_ctx *ctx;
 
@@ -134,22 +129,22 @@ static inline struct recv_ctx *create_recv_ctx(int handle)
        ctx->packet = NULL;
        ctx->handle = handle;
        ctx->pid = (pid_t)-1;
+       ctx->timeout = timeout;
 
        s_info.recv_list = dlist_append(s_info.recv_list, ctx);
        return ctx;
 }
 
-static inline void packet_ready(int handle, const struct recv_ctx *receive, struct method *table)
+static inline int packet_ready(int handle, const struct recv_ctx *receive, struct method *table)
 {
        struct request_ctx *request;
-       unsigned long sequence;
+       double sequence;
        struct packet *result;
        register int i;
+       int ret;
+
+       ret = 0;
 
-       /*!
-        * \note
-        * Is this ack packet?
-        */
        switch (packet_type(receive->packet)) {
        case PACKET_ACK:
                sequence = packet_seq(receive->packet);
@@ -171,10 +166,12 @@ static inline void packet_ready(int handle, const struct recv_ctx *receive, stru
 
                        result = table[i].handler(receive->pid, handle, receive->packet);
                        if (result) {
-                               int ret;
-                               ret = secure_socket_send(handle, (void *)packet_data(result), packet_size(result));
-                               if (ret < 0)
+                               ret = com_core_send(handle, (void *)packet_data(result), packet_size(result), DEFAULT_TIMEOUT);
+                               if (ret < 0) {
                                        ErrPrint("Failed to send an ack packet\n");
+                               } else {
+                                       ret = 0;
+                               }
                                packet_destroy(result);
                        }
                        break;
@@ -195,7 +192,10 @@ static inline void packet_ready(int handle, const struct recv_ctx *receive, stru
                break;
        }
 
-       return;
+       /*!
+        * Return negative value will make call the disconnected_cb
+        */
+       return ret;
 }
 
 static int client_disconnected_cb(int handle, void *data)
@@ -206,27 +206,28 @@ static int client_disconnected_cb(int handle, void *data)
        struct dlist *n;
        pid_t pid = (pid_t)-1;
 
-       DbgPrint("Clean up all requests and a receive context\n");
-
        receive = find_recv_ctx(handle);
        if (receive) {
                pid = receive->pid;
                destroy_recv_ctx(receive);
        }
 
+       DbgPrint("Clean up all requests and a receive context for handle(%d) for pid(%d)\n", handle, pid);
+
        dlist_foreach_safe(s_info.request_list, l, n, request) {
-               if (request->handle == handle) {
-                       if (request->recv_cb)
-                               request->recv_cb(pid, handle, NULL, request->data);
+               if (request->handle != handle)
+                       continue;
 
-                       destroy_request_ctx(request);
-               }
+               if (request->recv_cb)
+                       request->recv_cb(pid, handle, NULL, request->data);
+
+               destroy_request_ctx(request);
        }
 
        return 0;
 }
 
-static int service_cb(int handle, int readsize, void *data)
+static int service_cb(int handle, void *data)
 {
        struct recv_ctx *receive;
        pid_t pid;
@@ -236,37 +237,39 @@ static int service_cb(int handle, int readsize, void *data)
 
        receive = find_recv_ctx(handle);
        if (!receive)
-               receive = create_recv_ctx(handle);
+               receive = create_recv_ctx(handle, DEFAULT_TIMEOUT);
 
        if (!receive) {
                ErrPrint("Couldn't find or create a receive context\n");
                return -EIO;
        }
 
-       while (readsize > 0) {
-               switch (receive->state) {
-               case RECV_STATE_INIT:
-                       receive->state = RECV_STATE_HEADER;
-                       receive->offset = 0;
-               case RECV_STATE_HEADER:
-                       size = packet_header_size() - receive->offset;
-                       /*!
-                        * \note
-                        * Getting header
-                        */
-                       ptr = malloc(size);
-                       if (!ptr) {
-                               ErrPrint("Heap: %s\n", strerror(errno));
-                               destroy_recv_ctx(receive);
-                               return -ENOMEM;
-                       }
+       switch (receive->state) {
+       case RECV_STATE_INIT:
+               receive->state = RECV_STATE_HEADER;
+               receive->offset = 0;
+       case RECV_STATE_HEADER:
+               size = packet_header_size() - receive->offset;
+               /*!
+                * \note
+                * Getting header
+                */
+               ptr = malloc(size);
+               if (!ptr) {
+                       ErrPrint("Heap: %s\n", strerror(errno));
+                       return -ENOMEM;
+               }
 
-                       ret = secure_socket_recv(handle, ptr, size, &pid);
-                       if (ret < 0 || (receive->pid != -1 && receive->pid != pid)) {
+               ret = com_core_recv(handle, ptr, size, &pid, receive->timeout);
+               if (ret < 0) {
+                       ErrPrint("Recv[%d], pid[%d :: %d]\n", ret, receive->pid, pid);
+                       free(ptr);
+                       return -EIO; /*!< Return negative value will invoke the client_disconnected_cb */
+               } else if (ret > 0) {
+                       if (receive->pid != -1 && receive->pid != pid) {
                                ErrPrint("Recv[%d], pid[%d :: %d]\n", ret, receive->pid, pid);
                                free(ptr);
-                               destroy_recv_ctx(receive);
-                               return -EIO;
+                               return -EIO; /*!< Return negative value will invoke the client_disconnected_cb */
                        }
 
                        receive->pid = pid;
@@ -275,41 +278,48 @@ static int service_cb(int handle, int readsize, void *data)
 
                        if (!receive->packet) {
                                ErrPrint("Built packet is not valid\n");
-                               destroy_recv_ctx(receive);
-                               return -EFAULT;
+                               return -EFAULT; /*!< Return negative value will invoke the client_disconnected_cb */
                        }
 
                        receive->offset += ret;
-                       readsize -= ret;
+
                        if (receive->offset == packet_header_size()) {
                                if (packet_size(receive->packet) == receive->offset)
                                        receive->state = RECV_STATE_READY;
                                else
                                        receive->state = RECV_STATE_BODY;
                        }
+               } else {
+                       DbgPrint("ZERO bytes receives(%d)\n", pid);
+                       free(ptr);
+                       return -ECONNRESET;
+               }
+               break;
+       case RECV_STATE_BODY:
+               size = packet_size(receive->packet) - receive->offset;
+               if (size == 0) {
+                       receive->state = RECV_STATE_READY;
                        break;
-               case RECV_STATE_BODY:
-                       size = packet_size(receive->packet) - receive->offset;
-                       if (size == 0) {
-                               receive->state = RECV_STATE_READY;
-                               break;
-                       }
-                       /*!
-                        * \note
-                        * Getting body
-                        */
-                       ptr = malloc(size);
-                       if (!ptr) {
-                               ErrPrint("Heap: %s\n", strerror(errno));
-                               destroy_recv_ctx(receive);
-                               return -ENOMEM;
-                       }
+               }
+               /*!
+                * \note
+                * Getting body
+                */
+               ptr = malloc(size);
+               if (!ptr) {
+                       ErrPrint("Heap: %s\n", strerror(errno));
+                       return -ENOMEM;
+               }
 
-                       ret = secure_socket_recv(handle, ptr, size, &pid);
-                       if (ret < 0 || receive->pid != pid) {
+               ret = com_core_recv(handle, ptr, size, &pid, receive->timeout);
+               if (ret < 0) {
+                       ErrPrint("Recv[%d], pid[%d :: %d]\n", ret, receive->pid, pid);
+                       free(ptr);
+                       return -EIO;
+               } else if (ret > 0) {
+                       if (receive->pid != pid) {
                                ErrPrint("Recv[%d], pid[%d :: %d]\n", ret, receive->pid, pid);
                                free(ptr);
-                               destroy_recv_ctx(receive);
                                return -EIO;
                        }
 
@@ -317,55 +327,50 @@ static int service_cb(int handle, int readsize, void *data)
                        free(ptr);
 
                        if (!receive->packet) {
-                               destroy_recv_ctx(receive);
+                               ErrPrint("Built packet is not valid\n");
                                return -EFAULT;
                        }
 
                        receive->offset += ret;
-                       readsize -= ret;
+
                        if (receive->offset == packet_size(receive->packet))
                                receive->state = RECV_STATE_READY;
-                       break;
-               case RECV_STATE_READY:
-               default:
-                       break;
+               } else {
+                       DbgPrint("ZERO bytes receives(%d)\n", pid);
+                       free(ptr);
+                       return -ECONNRESET;
                }
 
-               if (receive->state == RECV_STATE_READY) {
-                       packet_ready(handle, receive, data);
-                       destroy_recv_ctx(receive);
-                       /*!
-                        * \note
-                        * Just quit from this function
-                        * Even if we have read size
-                        * Next time is comming soon ;)
-                        */
-                       break;
-               }
+               break;
+       case RECV_STATE_READY:
+       default:
+               break;
        }
 
-       return 0;
-}
-
-static gboolean timeout_cb(gpointer data)
-{
-       struct request_ctx *ctx = data;
-
-       ErrPrint("Timeout (Not responding in time)\n");
-
-       if (ctx->recv_cb)
-               ctx->recv_cb(ctx->pid, ctx->handle, NULL, ctx->data);
+       if (receive->state == RECV_STATE_READY) {
+               ret = packet_ready(handle, receive, data);
+               if (ret == 0)
+                       destroy_recv_ctx(receive);
+               /*!
+                * if ret is negative value, disconnected_cb will be called after this function
+                */
+       } else {
+               ret = 0;
+       }
 
-       ctx->timeout = 0u;
-       destroy_request_ctx(ctx);
-       return FALSE;
+       return ret;
 }
 
-EAPI int com_core_packet_async_send(int handle, struct packet *packet, unsigned int timeout, int (*recv_cb)(pid_t pid, int handle, const struct packet *packet, void *data), void *data)
+EAPI int com_core_packet_async_send(int handle, struct packet *packet, double timeout, int (*recv_cb)(pid_t pid, int handle, const struct packet *packet, void *data), void *data)
 {
        int ret;
        struct request_ctx *ctx;
 
+       if (packet_type(packet) != PACKET_REQ) {
+               ErrPrint("Invalid packet - should be PACKET_REQ\n");
+               return -EINVAL;
+       }
+
        ctx = create_request_ctx(handle);
        if (!ctx)
                return -ENOMEM;
@@ -373,13 +378,8 @@ EAPI int com_core_packet_async_send(int handle, struct packet *packet, unsigned
        ctx->recv_cb = recv_cb;
        ctx->data = data;
        ctx->packet = packet_ref(packet);
-       if (timeout > 0) {
-               ctx->timeout = g_timeout_add(timeout, timeout_cb, ctx);
-               if (ctx->timeout == 0)
-                       ErrPrint("Failed to add timeout\n");
-       }
 
-       ret = secure_socket_send(handle, (void *)packet_data(packet), packet_size(packet));
+       ret = com_core_send(handle, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT);
        if (ret != packet_size(packet)) {
                ErrPrint("Send failed. %d <> %d (handle: %d)\n", ret, packet_size(packet), handle);
                destroy_request_ctx(ctx);
@@ -393,24 +393,28 @@ EAPI int com_core_packet_send_only(int handle, struct packet *packet)
 {
        int ret;
 
-       ret = secure_socket_send(handle, (void *)packet_data(packet), packet_size(packet));
-       if (ret != packet_size(packet))
+       if (packet_type(packet) != PACKET_REQ_NOACK) {
+               ErrPrint("Invalid type - should be PACKET_REQ_NOACK\n");
+               return -EINVAL;
+       }
+
+       ret = com_core_send(handle, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT);
+       if (ret != packet_size(packet)) {
+               ErrPrint("Failed to send whole packet\n");
                return -EIO;
+       }
 
        return 0;
 }
 
-EAPI struct packet *com_core_packet_oneshot_send(const char *addr, struct packet *packet)
+EAPI struct packet *com_core_packet_oneshot_send(const char *addr, struct packet *packet, double timeout)
 {
        int ret;
-       int sz;
        int fd;
        pid_t pid;
        int offset;
        struct packet *result = NULL;
        void *ptr;
-       struct timeval timeout;
-       fd_set set;
 
        fd = secure_socket_create_client(addr);
        if (fd < 0)
@@ -424,96 +428,60 @@ EAPI struct packet *com_core_packet_oneshot_send(const char *addr, struct packet
        if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
                ErrPrint("Error: %s\n", strerror(errno));
 
-       ret = secure_socket_send(fd, (char *)packet_data(packet), packet_size(packet));
-       if (ret < 0) {
-               secure_socket_destroy(fd);
-               return NULL;
-       }
-       DbgPrint("Sent: %d bytes (%d bytes)\n", ret, packet_size(packet));
-
-       FD_ZERO(&set);
-       FD_SET(fd, &set);
-
-       timeout.tv_sec = DEFAULT_TIMEOUT;
-       timeout.tv_usec = 0;
-
-       ret = select(fd + 1, &set, NULL, NULL, &timeout);
-       if (ret < 0) {
-               ErrPrint("Error: %s\n", strerror(errno));
-               secure_socket_destroy(fd);
-               return NULL;
-       } else if (ret != 1) {
-               ErrPrint("Timeout (%d)\n", ret);
-               secure_socket_destroy(fd);
-               return NULL;
-       }
-
-       if (!FD_ISSET(fd, &set)) {
-               ErrPrint("Invalid handle\n");
-               secure_socket_destroy(fd);
-               return NULL;
-       }
-
-       if (ioctl(fd, FIONREAD, &sz) < 0 || sz == 0) {
-               ErrPrint("Connection closed\n");
-               secure_socket_destroy(fd);
-               return NULL;
-       }
+       ret = com_core_send(fd, (char *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT);
+       if (ret < 0)
+               goto out;
 
-       DbgPrint("Readable size: %d\n", sz);
-       if (sz < packet_header_size()) {
-               ErrPrint("Invalid packet [SIZE: %d]\n", sz);
-               secure_socket_destroy(fd);
-               return NULL;
-       }
+       DbgPrint("Sent: %d bytes (%d bytes)\n", ret, packet_size(packet));
 
-       offset = 0;
        ptr = malloc(packet_header_size());
        if (!ptr) {
                ErrPrint("Heap: %s\n", strerror(errno));
-               secure_socket_destroy(fd);
-               return NULL;
+               goto out;
        }
 
-       ret = secure_socket_recv(fd, (char *)ptr, packet_header_size(), &pid);
-       if (ret < 0) {
+       offset = 0;
+       ret = com_core_recv(fd, (char *)ptr, packet_header_size(), &pid, timeout);
+       if (ret <= 0) {
+               DbgPrint("Recv returns %s\n", ret);
                free(ptr);
-               secure_socket_destroy(fd);
-               return NULL;
+               goto out;
+       } else {
+               DbgPrint("Recv'd size: %d (header: %d) pid: %d\n", ret, packet_header_size(), pid);
+               result = packet_build(result, offset, ptr, ret);
+               offset += ret;
+               free(ptr);
+               if (!result) {
+                       ErrPrint("Failed to build a packet\n");
+                       goto out;
+               }
        }
-       DbgPrint("Recv'd size: %d (header: %d)\n", ret, packet_header_size());
-       result = packet_build(result, offset, ptr, ret);
-       offset += ret;
-       free(ptr);
 
        DbgPrint("Payload size: %d\n", packet_payload_size(result));
-       if (sz < packet_payload_size(result) + packet_header_size()) {
-               ErrPrint("Invalid packet [%d <> %d]\n", sz, packet_payload_size(result) + packet_header_size());
-               secure_socket_destroy(fd);
-               packet_destroy(result);
-               return NULL;
-       }
 
        ptr = malloc(packet_payload_size(result));
        if (!ptr) {
                ErrPrint("Heap: %s\n", strerror(errno));
-               secure_socket_destroy(fd);
                packet_destroy(result);
-               return NULL;
+               result = NULL;
+               goto out;
        }
 
-       ret = secure_socket_recv(fd, (char *)ptr, packet_payload_size(result), &pid);
-       if (ret < 0) {
+       ret = com_core_recv(fd, (char *)ptr, packet_payload_size(result), &pid, timeout);
+       if (ret <= 0) {
+               DbgPrint("Recv returns %s\n", ret);
                free(ptr);
-               secure_socket_destroy(fd);
                packet_destroy(result);
-               return NULL;
+               result = NULL;
+       } else {
+               DbgPrint("Recv'd %d bytes (pid: %d)\n", ret, pid);
+               result = packet_build(result, offset, ptr, ret);
+               offset += ret;
+               free(ptr);
        }
-       result = packet_build(result, offset, ptr, ret);
-       offset += ret;
-       free(ptr);
 
-       secure_socket_destroy(fd);
+out:
+       secure_socket_destroy_handle(fd);
        DbgPrint("Close connection: %d\n", fd);
        return result;
 }
index efaa45d..14f078a 100644 (file)
@@ -3,6 +3,7 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
+#include <sys/time.h>
 
 #include <dlog.h>
 
 
 int errno;
 
-struct {
-       unsigned long seq;
-} s_info = {
-       .seq = 0lu,
-};
-
 struct data {
        struct {
                int version;
                int payload_size;
                char command[PACKET_MAX_CMD];
                enum packet_type type;
-               unsigned long seq;
+               double seq;
        } head;
 
        char payload[];
@@ -70,7 +65,7 @@ EAPI const int const packet_size(const struct packet *packet)
        return sizeof(*packet->data) + packet->data->head.payload_size;
 }
 
-EAPI const unsigned long const packet_seq(const struct packet *packet)
+EAPI const double const packet_seq(const struct packet *packet)
 {
        if (!packet || packet->state != VALID || !packet->data)
                return 0;
@@ -231,6 +226,7 @@ EAPI struct packet *packet_create(const char *cmd, const char *fmt, ...)
        struct packet *packet;
        int payload_size;
        va_list va;
+       struct timeval tv;
 
        if (strlen(cmd) >= PACKET_MAX_CMD) {
                ErrPrint("Command is too long\n");
@@ -254,7 +250,8 @@ EAPI struct packet *packet_create(const char *cmd, const char *fmt, ...)
        }
 
        packet->state = VALID;
-       packet->data->head.seq = s_info.seq++;
+       gettimeofday(&tv, NULL);
+       packet->data->head.seq = tv.tv_sec + tv.tv_usec / 1000000.0f;
        packet->data->head.type = PACKET_REQ;
        packet->data->head.version = PACKET_VERSION;
        strncpy(packet->data->head.command, cmd, sizeof(packet->data->head.command));
@@ -273,6 +270,7 @@ EAPI struct packet *packet_create_noack(const char *cmd, const char *fmt, ...)
        int payload_size;
        struct packet *result;
        va_list va;
+       struct timeval tv;
 
        if (strlen(cmd) >= PACKET_MAX_CMD) {
                ErrPrint("Command is too long\n");
@@ -296,7 +294,8 @@ EAPI struct packet *packet_create_noack(const char *cmd, const char *fmt, ...)
        }
 
        result->state = VALID;
-       result->data->head.seq = s_info.seq++;
+       gettimeofday(&tv, NULL);
+       result->data->head.seq = tv.tv_sec + tv.tv_usec / 1000000.0f;
        result->data->head.type = PACKET_REQ_NOACK;
        result->data->head.version = PACKET_VERSION;
        strncpy(result->data->head.command, cmd, sizeof(result->data->head.command));
index eabd5ee..84d2d7b 100644 (file)
@@ -138,16 +138,6 @@ EAPI int secure_socket_get_connection_handle(int server_handle)
        return handle;
 }
 
-EAPI int secure_socket_remove_connection_handle(int conn_handle)
-{
-       if (close(conn_handle) < 0) {
-               ErrPrint("Close a handle: %s\n", strerror(errno));
-               return -1;
-       }
-
-       return 0;
-}
-
 EAPI int secure_socket_send(int handle, const char *buffer, int size)
 {
        struct msghdr msg;
@@ -156,7 +146,7 @@ EAPI int secure_socket_send(int handle, const char *buffer, int size)
 
        if (!buffer || size <= 0) {
                ErrPrint("Reject: 0 byte data sending\n");
-               return -1;
+               return -EINVAL;
        }
 
        memset(&msg, 0, sizeof(msg));
@@ -167,12 +157,13 @@ EAPI int secure_socket_send(int handle, const char *buffer, int size)
 
        ret = sendmsg(handle, &msg, 0);
        if (ret < 0) {
+               ret = -errno;
                if (errno == EAGAIN || errno == EWOULDBLOCK) {
                        ErrPrint("handle[%d] size[%d] Try again [%s]\n", handle, size, strerror(errno));
-                       return 0;
+                       return -EAGAIN;
                }
                ErrPrint("Failed to send message [%s]\n", strerror(errno));
-               return -1;
+               return ret;
        }
 
        return iov.iov_len;
@@ -184,9 +175,10 @@ EAPI int secure_socket_recv(int handle, char *buffer, int size, int *sender_pid)
        struct cmsghdr *cmsg;
        struct iovec iov;
        char control[1024];
+       int ret;
 
        if (!sender_pid || size <= 0 || !buffer)
-               return -1;
+               return -EINVAL;
 
        memset(&msg, 0, sizeof(msg));
        iov.iov_base = buffer;
@@ -196,14 +188,22 @@ EAPI int secure_socket_recv(int handle, char *buffer, int size, int *sender_pid)
        msg.msg_control = control;
        msg.msg_controllen = sizeof(control);
 
-       if (recvmsg(handle, &msg, 0) < 0) {
+       ret = recvmsg(handle, &msg, 0);
+       if (ret == 0) {
+               /*!< Disconnected */
+               DbgPrint("Disconnected\n");
+               return 0;
+       }
+
+       if (ret < 0) {
+               ret = -errno;
                if (errno == EAGAIN || errno == EWOULDBLOCK) {
                        ErrPrint("handle[%d] size[%d] Try again [%s]\n", handle, size, strerror(errno));
-                       return 0;
+                       return -EAGAIN;
                }
 
                ErrPrint("Failed to recvmsg [%s]\n", strerror(errno));
-               return -1;
+               return ret;
        }
 
        cmsg = CMSG_FIRSTHDR(&msg);
@@ -221,8 +221,9 @@ EAPI int secure_socket_recv(int handle, char *buffer, int size, int *sender_pid)
        return iov.iov_len;
 }
 
-EAPI int secure_socket_destroy(int handle)
+EAPI int secure_socket_destroy_handle(int handle)
 {
+       DbgPrint("Close socket handle %d\n", handle);
        if (close(handle) < 0) {
                ErrPrint("Failed to close a handle: %s\n", strerror(errno));
                return -1;