summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSung-jae Park <nicesj.park@samsung.com>2013-08-03 13:51:53 +0900
committerSung-jae Park <nicesj.park@samsung.com>2013-08-03 13:51:53 +0900
commit835a6a0b53856d7b417a9b040ebe7bf5f298427f (patch)
tree1f94021d8fe08174a119f85a4e08a7697ae08a45
parentccb9e303b332ee938e8ebe4e789026c2ad2fe97b (diff)
parentb1b1264655cfc12a60dfb6ec172bd91d04708d5c (diff)
downloadcom-core-835a6a0b53856d7b417a9b040ebe7bf5f298427f.tar.gz
com-core-835a6a0b53856d7b417a9b040ebe7bf5f298427f.tar.bz2
com-core-835a6a0b53856d7b417a9b040ebe7bf5f298427f.zip
Merge branch 'devel/home/master'
-rw-r--r--include/secure_socket.h12
-rw-r--r--packaging/libcom-core.spec8
-rw-r--r--src/com-core_packet-router.c2
-rw-r--r--src/secure_socket.c352
4 files changed, 284 insertions, 90 deletions
diff --git a/include/secure_socket.h b/include/secure_socket.h
index 64a7832..c5c7c35 100644
--- a/include/secure_socket.h
+++ b/include/secure_socket.h
@@ -22,6 +22,18 @@
extern "C" {
#endif
+/*!
+ * local:///tmp/.socket.file => /tmp/.socket.file
+ */
+#define COM_CORE_LOCAL_SCHEME "local://"
+#define COM_CORE_LOCAL_SCHEME_LEN (8)
+
+/*!
+ * remote://IPADDR:PORT
+ * remote://:PORT => Using INADDR_ANY in this case
+ */
+#define COM_CORE_REMOTE_SCHEME "remote://"
+#define COM_CORE_REMOTE_SCHEME_LEN (9)
/*
* Create client connection
diff --git a/packaging/libcom-core.spec b/packaging/libcom-core.spec
index b4abc22..facc9d8 100644
--- a/packaging/libcom-core.spec
+++ b/packaging/libcom-core.spec
@@ -1,6 +1,6 @@
Name: libcom-core
Summary: Library for the light-weight IPC
-Version: 0.4.5
+Version: 0.5.0
Release: 1
Group: HomeTF/Framework
License: Apache License
@@ -24,6 +24,12 @@ Light-weight IPC supporting library (dev)
%setup -q
%build
+%if 0%{?tizen_build_binary_release_type_eng}
+export CFLAGS="${CFLAGS} -DTIZEN_ENGINEER_MODE"
+export CXXFLAGS="${CXXFLAGS} -DTIZEN_ENGINEER_MODE"
+export FFLAGS="${FFLAGS} -DTIZEN_ENGINEER_MODE"
+%endif
+
cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix}
make %{?jobs:-j%jobs}
diff --git a/src/com-core_packet-router.c b/src/com-core_packet-router.c
index 57f45d0..f716751 100644
--- a/src/com-core_packet-router.c
+++ b/src/com-core_packet-router.c
@@ -888,7 +888,7 @@ static inline int route_packet(struct router *router, int handle, struct packet
* \NOTE
* Running Threads: Main / Client / Server
*/
-static inline int put_send_packet(struct router *router, int handle, struct packet *packet)
+static int put_send_packet(struct router *router, int handle, struct packet *packet)
{
if (packet) {
struct packet_item *item;
diff --git a/src/secure_socket.c b/src/secure_socket.c
index 98185c7..d3ae477 100644
--- a/src/secure_socket.c
+++ b/src/secure_socket.c
@@ -22,11 +22,13 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
+#include <netdb.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <errno.h>
+#include <stdlib.h>
#include <dlog.h>
@@ -34,21 +36,34 @@
#include "debug.h"
#include "util.h"
-#define BACKLOG 50 /*!< Accept only 50 connections as default */
-#define SNDBUF_SZ 262144
-#define RCVBUF_SZ 524288
+#define BACKLOG 50 /*!< Accept only 50 connections as default */
+#define SNDBUF_SZ 262144 /*!< 256 KB, this will be doubled by kernel */
+#define RCVBUF_SZ 524288 /*!< 512 KB, this will be doubled by kernel */
+
+enum scheme {
+ SCHEME_LOCAL = 0x00,
+ SCHEME_REMOTE = 0x01,
+ SCHEME_UNKNOWN = 0x02,
+};
+
+struct function_table {
+ int type;
+ int (*create_socket)(const char *peer, int port, struct sockaddr *addr);
+ int (*setup_handle)(int handle);
+};
int errno;
-static inline int create_socket(const char *peer, struct sockaddr_un *addr)
+static inline int create_unix_socket(const char *peer, int port, struct sockaddr *addr)
{
int len;
int handle;
+ struct sockaddr_un *un_addr = (struct sockaddr_un *)addr;
- len = sizeof(*addr);
- bzero(addr, len);
+ len = sizeof(*un_addr);
+ bzero(un_addr, len);
- if (strlen(peer) >= sizeof(addr->sun_path)) {
+ if (strlen(peer) >= sizeof(un_addr->sun_path)) {
ErrPrint("peer %s is too long to remember it\\n", peer);
return -1;
}
@@ -56,8 +71,8 @@ static inline int create_socket(const char *peer, struct sockaddr_un *addr)
/* We can believe this has no prob, because
* we already check the size of add.rsun_path
*/
- strcpy(addr->sun_path, peer);
- addr->sun_family = AF_UNIX;
+ strcpy(un_addr->sun_path, peer);
+ un_addr->sun_family = AF_UNIX;
handle = socket(PF_UNIX, SOCK_STREAM, 0);
if (handle < 0) {
@@ -68,52 +83,183 @@ static inline int create_socket(const char *peer, struct sockaddr_un *addr)
return handle;
}
-EAPI int secure_socket_create_client(const char *peer)
+static inline int create_inet_socket(const char *peer, int port, struct sockaddr *addr)
{
- struct sockaddr_un addr;
int handle;
- int state;
+ struct sockaddr_in *in_addr = (struct sockaddr_in *)addr;
+
+ bzero(in_addr, sizeof(*in_addr));
+
+ in_addr->sin_port = htons(port);
+ in_addr->sin_family = AF_INET;
+ if (*peer == '\0')
+ in_addr->sin_addr.s_addr = htonl(INADDR_ANY);
+ else
+ in_addr->sin_addr.s_addr = inet_addr(peer);
+
+ handle = socket(AF_INET, SOCK_STREAM, 0);
+ if (handle < 0) {
+ handle = -errno;
+ ErrPrint("socket: %s\n", strerror(errno));
+ }
+
+ return handle;
+}
+
+static inline int setup_unix_handle(int handle)
+{
int on = 1;
int sndbuf = SNDBUF_SZ;
int rcvbuf = RCVBUF_SZ;
- handle = create_socket(peer, &addr);
+ if (setsockopt(handle, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {
+ int ret;
+ ret = -errno;
+ ErrPrint("Failed to change sock opt : %s\n", strerror(errno));
+ return ret;
+ }
+
+ (void)setsockopt(handle, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
+ (void)setsockopt(handle, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));
+ (void)setsockopt(handle, IPPROTO_IP, TCP_NODELAY, &on, sizeof(on));
+
+ return 0;
+}
+
+static inline int setup_inet_handle(int handle)
+{
+ int on = 1;
+
+ (void)setsockopt(handle, IPPROTO_IP, TCP_NODELAY, &on, sizeof(on));
+
+ return 0;
+}
+
+static inline char *parse_scheme(const char *peer, int *port, struct function_table *vtable)
+{
+ int _port;
+ char *addr = NULL;
+
+ if (!port)
+ port = &_port;
+
+ *port = 0;
+
+ if (!strncasecmp(peer, COM_CORE_LOCAL_SCHEME, COM_CORE_LOCAL_SCHEME_LEN)) {
+ vtable->type = (int)SCHEME_LOCAL;
+ peer += COM_CORE_LOCAL_SCHEME_LEN;
+
+ addr = strdup(peer);
+ if (!addr)
+ ErrPrint("Heap: %s\n", strerror(errno));
+
+ vtable->create_socket = create_unix_socket;
+ vtable->setup_handle = setup_unix_handle;
+ } else if (!strncasecmp(peer, COM_CORE_REMOTE_SCHEME, COM_CORE_REMOTE_SCHEME_LEN)) {
+ register int len;
+ char *endptr;
+
+ vtable->type = (int)SCHEME_REMOTE;
+ peer += COM_CORE_REMOTE_SCHEME_LEN;
+
+ for (len = 0; peer[len] && peer[len] != ':'; len++);
+ if (peer[len] != ':') {
+ ErrPrint("Invalid syntax: %s\n", peer);
+ goto out;
+ }
+
+ addr = malloc(len + 1);
+ if (!addr) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ goto out;
+ }
+
+ if (len > 0)
+ strncpy(addr, peer, len);
+ addr[len] = '\0';
+
+ peer += len + 1;
+ *port = strtoul(peer, &endptr, 10);
+ if (*endptr != '\0' || peer == endptr) {
+ ErrPrint("Invalid: %s[%d]\n", peer - len - 1, len + 1);
+ free(addr);
+ addr = NULL;
+ goto out;
+ }
+
+ vtable->create_socket = create_inet_socket;
+ vtable->setup_handle = setup_inet_handle;
+ } else {
+ /* Fallback to local scheme */
+ vtable->type = (int)SCHEME_LOCAL;
+ addr = strdup(peer);
+ if (!addr) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ goto out;
+ }
+
+ vtable->create_socket = create_unix_socket;
+ vtable->setup_handle = setup_unix_handle;
+ }
+
+out:
+ return addr;
+}
+
+EAPI int secure_socket_create_client(const char *peer)
+{
+ int port;
+ char *addr;
+ int ret;
+ struct function_table vtable;
+ struct sockaddr *sockaddr;
+ struct sockaddr_in in_addr;
+ struct sockaddr_un un_addr;
+ int handle;
+ int addrlen;
+
+ addr = parse_scheme(peer, &port, &vtable);
+ if (!addr) {
+ ErrPrint("peer: [%s] is not valid\n", peer);
+ return -EINVAL;
+ }
+
+ switch (vtable.type) {
+ case SCHEME_LOCAL:
+ sockaddr = (struct sockaddr *)&un_addr;
+ addrlen = sizeof(un_addr);
+ break;
+ case SCHEME_REMOTE:
+ sockaddr = (struct sockaddr *)&in_addr;
+ addrlen = sizeof(in_addr);
+ break;
+ default:
+ free(addr);
+ return -EINVAL;
+ }
+
+ handle = vtable.create_socket(addr, port, sockaddr);
+ free(addr);
if (handle < 0)
return handle;
- state = connect(handle, (struct sockaddr *)&addr, sizeof(addr));
- if (state < 0) {
+ ret = connect(handle, sockaddr, addrlen);
+ if (ret < 0) {
+ ret = -errno;
ErrPrint("Failed to connect to server [%s] %s\n",
peer, strerror(errno));
if (close(handle) < 0)
ErrPrint("close: %s\n", strerror(errno));
- return -ENOTCONN;
+ return ret;
}
- if (setsockopt(handle, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {
- ErrPrint("Failed to change sock opt : %s\n", strerror(errno));
+ ret = vtable.setup_handle(handle);
+ if (ret < 0) {
if (close(handle) < 0)
ErrPrint("close: %s\n", strerror(errno));
- return -EFAULT;
- }
-
- if (setsockopt(handle, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) < 0) {
- ErrPrint("Failed to change rcvbuf size: %s\n", strerror(errno));
- } else {
- DbgPrint("rcvbuf: %d\n", rcvbuf);
- }
-
- if (setsockopt(handle, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) < 0) {
- ErrPrint("Failed to change rcvbuf size: %s\n", strerror(errno));
- } else {
- DbgPrint("sndbuf: %d\n", sndbuf);
- }
- if (setsockopt(handle, IPPROTO_IP, TCP_NODELAY, &on, sizeof(on)) < 0) {
- ErrPrint("Failed to change rcvbuf size: %s\n", strerror(errno));
- } else {
- DbgPrint("TCP_NODELAY: %d\n", on);
+ return ret;
}
return handle;
@@ -121,84 +267,110 @@ EAPI int secure_socket_create_client(const char *peer)
EAPI int secure_socket_create_server(const char *peer)
{
+ int port;
+ char *addr;
int handle;
- int state;
- struct sockaddr_un addr;
+ int ret;
+ struct sockaddr *sockaddr;
+ struct sockaddr_in in_addr;
+ struct sockaddr_un un_addr;
+ struct function_table vtable;
+ int addrlen;
+
+ addr = parse_scheme(peer, &port, &vtable);
+ if (!addr) {
+ ErrPrint("Failed to parse scheme\n");
+ return -EFAULT;
+ }
- handle = create_socket(peer, &addr);
+ switch (vtable.type) {
+ case SCHEME_LOCAL:
+ sockaddr = (struct sockaddr *)&un_addr;
+ addrlen = sizeof(un_addr);
+ break;
+ case SCHEME_REMOTE:
+ sockaddr = (struct sockaddr *)&in_addr;
+ addrlen = sizeof(in_addr);
+ break;
+ default:
+ free(addr);
+ return -EINVAL;
+ }
+
+ handle = vtable.create_socket(addr, port, sockaddr);
+ free(addr);
if (handle < 0)
return handle;
- state = bind(handle, &addr, sizeof(addr));
- if (state < 0) {
- state = -errno;
-
- ErrPrint("Failed to bind a socket %s\n", strerror(errno));
+ ret = bind(handle, sockaddr, addrlen);
+ if (ret < 0) {
+ ret = -errno;
+ ErrPrint("bind: %s\n", strerror(errno));
if (close(handle) < 0)
ErrPrint("close: %s\n", strerror(errno));
-
- return state;
+ return ret;
}
- state = listen(handle, BACKLOG);
- if (state < 0) {
- state = -errno;
- ErrPrint("Failed to listen a socket %s\n", strerror(errno));
-
+ ret = listen(handle, BACKLOG);
+ if (ret < 0) {
+ ret = -errno;
+ ErrPrint("listen: %s\n", strerror(errno));
if (close(handle) < 0)
ErrPrint("close: %s\n", strerror(errno));
-
- return state;
+ return ret;
}
- if (chmod(peer, 0666) < 0)
- ErrPrint("Failed to change the permission of a socket (%s)\n",
- strerror(errno));
+ if (vtable.type == SCHEME_LOCAL) {
+ if (chmod(peer, 0666) < 0)
+ ErrPrint("Failed to change the permission of a socket (%s)\n", strerror(errno));
+ }
return handle;
}
EAPI int secure_socket_get_connection_handle(int server_handle)
{
- struct sockaddr_un addr;
+ struct sockaddr_in in_addr;
+ struct sockaddr_un un_addr;
+ struct sockaddr *addr;
int handle;
- int on = 1;
- socklen_t size = sizeof(addr);
- int sndbuf = SNDBUF_SZ;
- int rcvbuf = RCVBUF_SZ;
+ int ret;
+ socklen_t size = sizeof(un_addr);
- handle = accept(server_handle, (struct sockaddr *)&addr, &size);
- if (handle < 0) {
- handle = -errno;
- ErrPrint("Failed to accept a new client %s\n", strerror(errno));
- return handle;
+ /* Finding the largest buffer */
+ if (sizeof(in_addr) > sizeof(un_addr)) {
+ addr = (struct sockaddr *)&in_addr;
+ size = sizeof(in_addr);
+ } else {
+ addr = (struct sockaddr *)&un_addr;
+ size = sizeof(un_addr);
}
- if (setsockopt(handle, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {
- int ret;
+ handle = accept(server_handle, addr, &size);
+ if (handle < 0) {
ret = -errno;
- ErrPrint("Failed to change sock opt : %s\n", strerror(errno));
- if (close(handle) < 0)
- ErrPrint("close: %s\n", strerror(errno));
+ ErrPrint("Failed to accept a new client %s\n", strerror(errno));
return ret;
}
- if (setsockopt(handle, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) < 0) {
- ErrPrint("Failed to change rcvbuf size: %s\n", strerror(errno));
- } else {
- DbgPrint("rcvbuf: %d\n", rcvbuf);
- }
+ if (addr->sa_family == AF_UNIX) {
+ ret = setup_unix_handle(handle);
+ if (ret < 0) {
+ if (close(handle) < 0)
+ ErrPrint("close: %s\n", strerror(errno));
- if (setsockopt(handle, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) < 0) {
- ErrPrint("Failed to change rcvbuf size: %s\n", strerror(errno));
- } else {
- DbgPrint("sndbuf: %d\n", sndbuf);
- }
+ handle = ret;
+ }
+ } else if (addr->sa_family == AF_INET) {
+ ret = setup_inet_handle(handle);
+ if (ret < 0) {
+ if (close(handle) < 0)
+ ErrPrint("close: %s\n", strerror(errno));
- if (setsockopt(handle, IPPROTO_IP, TCP_NODELAY, &on, sizeof(on)) < 0) {
- ErrPrint("Failed to change rcvbuf size: %s\n", strerror(errno));
+ handle = ret;
+ }
} else {
- DbgPrint("TCP_NODELAY: %d\n", on);
+ ErrPrint("Unknown address family: %d\n", addr->sa_family);
}
return handle;
@@ -241,11 +413,15 @@ EAPI int secure_socket_recv(int handle, char *buffer, int size, int *sender_pid)
struct cmsghdr *cmsg;
struct iovec iov;
char control[1024];
+ int _pid;
int ret;
- if (!sender_pid || size <= 0 || !buffer)
+ if (size <= 0 || !buffer)
return -EINVAL;
+ if (!sender_pid)
+ sender_pid = &_pid;
+
memset(&msg, 0, sizeof(msg));
iov.iov_base = buffer;
iov.iov_len = size;
@@ -272,11 +448,12 @@ EAPI int secure_socket_recv(int handle, char *buffer, int size, int *sender_pid)
return ret;
}
+ *sender_pid = -1; /* In case of remote socket, cannot delivery this */
cmsg = CMSG_FIRSTHDR(&msg);
while (cmsg) {
- if (cmsg->cmsg_level == SOL_SOCKET
- && cmsg->cmsg_type == SCM_CREDENTIALS) {
+ if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) {
struct ucred *cred;
+
cred = (struct ucred *)CMSG_DATA(cmsg);
*sender_pid = cred->pid;
}
@@ -289,7 +466,6 @@ EAPI int secure_socket_recv(int handle, char *buffer, int size, int *sender_pid)
EAPI int secure_socket_destroy_handle(int handle)
{
- DbgPrint("Close socket handle %d\n", handle);
if (close(handle) < 0) {
ErrPrint("close: %s\n", strerror(errno));
return -1;