summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHyunho Kang <hhstark.kang@samsung.com>2016-01-11 19:26:12 +0900
committerHyunho Kang <hhstark.kang@samsung.com>2016-01-12 14:35:29 +0900
commit0f0ec1bc41366ca18e31855226415ba14bee589f (patch)
treeae631c73f452e38f87c26613bdc453353f09869a
parent7f0cbb64dd01d4210620ec04336fc93f3c26b662 (diff)
downloadmessage-port-0f0ec1bc41366ca18e31855226415ba14bee589f.tar.gz
message-port-0f0ec1bc41366ca18e31855226415ba14bee589f.tar.bz2
message-port-0f0ec1bc41366ca18e31855226415ba14bee589f.zip
Because of this bug, user can not receive remote app's port name when user send message with message_port_send_message_with_local_port right after message_port_send_message API call. Change-Id: Ic04fc05216e08ee0fc7a252c72ca3a23678d000e Signed-off-by: Hyunho Kang <hhstark.kang@samsung.com>
-rwxr-xr-xsrc/message-port.c242
1 files changed, 154 insertions, 88 deletions
diff --git a/src/message-port.c b/src/message-port.c
index b6b5a2a..b5a0364 100755
--- a/src/message-port.c
+++ b/src/message-port.c
@@ -91,17 +91,18 @@ enum __certificate_info_type {
};
typedef struct message_port_pkt {
- int len;
+ int remote_port_name_len;
+ char *remote_port_name;
bool is_bidirection;
- unsigned char data[1];
+ int data_len;
+ unsigned char *data;
} message_port_pkt_s;
typedef struct message_port_callback_info {
messageport_message_cb callback;
+ bool is_trusted;
int local_id;
char *remote_app_id;
- char *remote_port;
- bool is_trusted;
GIOChannel *gio_read;
int g_src_id;
} message_port_callback_info_s;
@@ -138,9 +139,6 @@ static void __callback_info_free(message_port_callback_info_s *callback_info)
if (callback_info->remote_app_id)
free(callback_info->remote_app_id);
- if (callback_info->remote_port)
- free(callback_info->remote_port);
-
if (callback_info->gio_read != NULL) {
g_io_channel_shutdown(callback_info->gio_read, FALSE, &error);
if (error) {
@@ -493,45 +491,137 @@ out:
return pid;
}
+static int __write_socket(int fd,
+ const char *buffer,
+ unsigned int nbytes,
+ unsigned int *bytes_write)
+{
+ unsigned int left = nbytes;
+ ssize_t nb;
+ int retry_cnt = 0;
+
+ *bytes_write = 0;
+ while (left && (retry_cnt < MAX_RETRY_CNT)) {
+ nb = write(fd, buffer, left);
+ if (nb == -1) {
+ if (errno == EINTR) {
+ LOGE("__write_socket: EINTR error continue ...");
+ retry_cnt++;
+ continue;
+ }
+ LOGE("__write_socket: ...error fd %d: errno %d\n", fd, errno);
+ return MESSAGEPORT_ERROR_IO_ERROR;
+ }
+
+ left -= nb;
+ buffer += nb;
+ *bytes_write += nb;
+ retry_cnt = 0;
+ }
+ return MESSAGEPORT_ERROR_NONE;
+}
+
+static int __write_string_to_socket(int fd, const char *buffer, int string_len)
+{
+ unsigned int nb;
+ if (__write_socket(fd, (char *)&string_len, sizeof(string_len), &nb) != MESSAGEPORT_ERROR_NONE) {
+ _LOGE("write string_len fail");
+ return MESSAGEPORT_ERROR_IO_ERROR;
+ }
+
+ if (string_len > 0) {
+ if (__write_socket(fd, buffer, string_len, &nb) != MESSAGEPORT_ERROR_NONE) {
+ _LOGE("wirte buffer fail");
+ return MESSAGEPORT_ERROR_IO_ERROR;
+ }
+ }
+ return MESSAGEPORT_ERROR_NONE;
+}
+
+static int __read_socket(int fd,
+ char *buffer,
+ unsigned int nbytes,
+ unsigned int *bytes_read)
+{
+ unsigned int left = nbytes;
+ ssize_t nb;
+ int retry_cnt = 0;
+
+ *bytes_read = 0;
+ while (left && (retry_cnt < MAX_RETRY_CNT)) {
+ nb = read(fd, buffer, left);
+ if (nb == 0) {
+ LOGE("__read_socket: ...read EOF, socket closed %d: nb %d\n", fd, nb);
+ return MESSAGEPORT_ERROR_IO_ERROR;
+ } else if (nb == -1) {
+ if (errno == EINTR) {
+ LOGE("__read_socket: EINTR error continue ...");
+ retry_cnt++;
+ continue;
+ }
+ LOGE("__read_socket: ...error fd %d: errno %d\n", fd, errno);
+ return MESSAGEPORT_ERROR_IO_ERROR;
+ }
+
+ left -= nb;
+ buffer += nb;
+ *bytes_read += nb;
+ retry_cnt = 0;
+ }
+ return MESSAGEPORT_ERROR_NONE;
+}
+
+static int __read_string_from_socket(int fd, char **buffer, int *string_len)
+{
+ unsigned int nb;
+ if (__read_socket(fd, (char *)string_len, sizeof(*string_len), &nb) != MESSAGEPORT_ERROR_NONE) {
+ LOGE("read socket fail");
+ return MESSAGEPORT_ERROR_IO_ERROR;
+ }
+ if (*string_len > 0) {
+ *buffer = (char *)calloc(*string_len, sizeof(char));
+ if (*buffer == NULL) {
+ LOGE("Out of memory.");
+ return MESSAGEPORT_ERROR_IO_ERROR;
+ }
+ if (__read_socket(fd, *buffer, *string_len, &nb) != MESSAGEPORT_ERROR_NONE) {
+ LOGE("read socket fail");
+ return MESSAGEPORT_ERROR_IO_ERROR;
+ }
+ }
+ return MESSAGEPORT_ERROR_NONE;
+}
+
message_port_pkt_s *__message_port_recv_raw(int fd)
{
- int len;
- int ret;
message_port_pkt_s *pkt = NULL;
+ unsigned int nb;
- pkt = (message_port_pkt_s *)calloc(sizeof(char) * MAX_MESSAGE_SIZE, 1);
+ pkt = (message_port_pkt_s *)calloc(sizeof(message_port_pkt_s), 1);
if (pkt == NULL) {
close(fd);
return NULL;
}
-
-retry_recv:
- /* receive single packet from socket */
- len = recv(fd, pkt, MAX_MESSAGE_SIZE, 0);
- if (len < 0) {
- _LOGE("recv error: %d[%s]", errno, strerror(errno));
- if (errno == EINTR)
- goto retry_recv;
+ if (__read_string_from_socket(fd, (char **)&pkt->remote_port_name, &pkt->remote_port_name_len) != MESSAGEPORT_ERROR_NONE) {
+ LOGE("read socket fail: port_name");
+ free(pkt->remote_port_name);
+ free(pkt);
+ close(fd);
+ return NULL;
}
-
- if (len < HEADER_LEN) {
- _LOGE("recv error %d %d", len, pkt->len);
+ if (__read_socket(fd, (char *)&pkt->is_bidirection, sizeof(pkt->is_bidirection), &nb) != MESSAGEPORT_ERROR_NONE) {
+ LOGE("read socket fail: is_bidirection");
+ free(pkt->remote_port_name);
free(pkt);
close(fd);
return NULL;
}
- while (len < (pkt->len + HEADER_LEN)) {
-retry_recv1:
- ret = recv(fd, &pkt->data[len - 8], MAX_MESSAGE_SIZE, 0);
- if (ret < 0) {
- SECURE_LOGE("recv error: %d %d %d", errno, len, pkt->len);
- if (errno == EINTR)
- goto retry_recv1;
- free(pkt);
- close(fd);
- return NULL;
- }
- len += ret;
+ if (__read_string_from_socket(fd, (char **)&pkt->data, &pkt->data_len) != MESSAGEPORT_ERROR_NONE) {
+ LOGE("read socket fail: data");
+ free(pkt->remote_port_name);
+ free(pkt);
+ close(fd);
+ return NULL;
}
return pkt;
}
@@ -544,7 +634,6 @@ static gboolean __socket_request_handler(GIOChannel *gio,
message_port_callback_info_s *mi;
message_port_pkt_s *pkt;
bundle *kb = NULL;
- bool is_bidirection;
GError *error = NULL;
mi = (message_port_callback_info_s *)data;
@@ -579,16 +668,20 @@ static gboolean __socket_request_handler(GIOChannel *gio,
return FALSE;
}
- kb = bundle_decode(pkt->data, pkt->len);
- is_bidirection = pkt->is_bidirection;
+ kb = bundle_decode(pkt->data, pkt->data_len);
- if (is_bidirection)
- mi->callback(mi->local_id, mi->remote_app_id, mi->remote_port, mi->is_trusted, kb, NULL);
+ if (pkt->is_bidirection)
+ mi->callback(mi->local_id, mi->remote_app_id, pkt->remote_port_name, mi->is_trusted, kb, NULL);
else
mi->callback(mi->local_id, mi->remote_app_id, NULL, mi->is_trusted, kb, NULL);
- if (pkt)
+ if (pkt) {
+ if (pkt->remote_port_name)
+ free(pkt->remote_port_name);
+ if (pkt->data)
+ free(pkt->data);
free(pkt);
+ }
}
return TRUE;
@@ -668,9 +761,8 @@ static bool send_message(GVariant *parameters, GDBusMethodInvocation *invocation
callback_info->local_id = mi->local_id;
callback_info->remote_app_id = strdup(local_appid);
- callback_info->remote_port = strdup(local_port);
- callback_info->is_trusted = local_trusted;
callback_info->callback = mi->callback;
+ callback_info->is_trusted = local_trusted;
GError *error = NULL;
GDBusMessage *msg = g_dbus_method_invocation_get_message(invocation);
@@ -1124,70 +1216,44 @@ static int __register_message_port(const char *local_port, bool is_trusted, mess
return local_id;
}
-int __message_port_send_async(int sockfd, bundle *kb, const char *app_id, const char *local_port,
+int __message_port_send_async(int sockfd, bundle *kb, const char *local_port,
bool local_trusted, bool is_bidirection)
{
-
- int len;
int ret = 0;
- message_port_pkt_s *pkt = NULL;
- int pkt_size;
-
- int datalen;
+ int data_len;
+ int local_port_len = 0;
+ unsigned int nb;
bundle_raw *kb_data = NULL;
- bundle_encode(kb, &kb_data, &datalen);
+ if (local_port != NULL)
+ local_port_len = strlen(local_port) + 1;
+
+ if (__write_string_to_socket(sockfd, local_port, local_port_len) != MESSAGEPORT_ERROR_NONE) {
+ _LOGE("write local_port fail");
+ return MESSAGEPORT_ERROR_IO_ERROR;
+ }
+ if (__write_socket(sockfd, (char *)&is_bidirection, sizeof(is_bidirection), &nb) != MESSAGEPORT_ERROR_NONE) {
+ _LOGE("write is_bidirection fail");
+ return MESSAGEPORT_ERROR_IO_ERROR;
+ }
+
+ bundle_encode(kb, &kb_data, &data_len);
if (kb_data == NULL) {
_LOGE("bundle encode fail");
ret = MESSAGEPORT_ERROR_IO_ERROR;
goto out;
}
-
- if (datalen > MAX_MESSAGE_SIZE - HEADER_LEN) {
+ if (data_len > MAX_MESSAGE_SIZE) {
_LOGE("bigger than max size\n");
ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
goto out;
}
- pkt_size = datalen + 9;
- pkt = (message_port_pkt_s *) malloc(sizeof(char) * pkt_size);
-
- if (NULL == pkt) {
- _LOGE("Malloc Failed!");
- ret = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
- goto out;
- }
- memset(pkt, 0, pkt_size);
-
- pkt->len = datalen;
- pkt->is_bidirection = is_bidirection;
-
- memcpy(pkt->data, kb_data, datalen);
-
- int retry_ctr = MAX_RETRY_CNT;
-
-retry_send:
- if ((len = send(sockfd, pkt, pkt_size, 0)) != pkt_size) {
- SECURE_LOGE("send() failed - len[%d] pkt_size[%d] (errno %d[%s])", len, pkt_size,
- errno, strerror(errno));
- if (errno == EPIPE)
- _LOGE("fd:%d\n", sockfd);
-
- if (errno == EINTR) {
- if (retry_ctr > 0) {
- _LOGI("Retrying send on fd[%d]", sockfd);
- usleep(30 * 1000);
-
- retry_ctr--;
- goto retry_send;
- }
- }
+ if (__write_string_to_socket(sockfd, (void *)kb_data, data_len) != MESSAGEPORT_ERROR_NONE) {
+ _LOGE("write kb_data fail");
ret = MESSAGEPORT_ERROR_IO_ERROR;
- goto out;
}
out:
- if (pkt)
- free(pkt);
if (kb_data)
free(kb_data);
@@ -1231,7 +1297,7 @@ static int __message_port_send_message(const char *remote_appid, const char *rem
if (port_info->sock_pair[0] > 0) {
ret = __message_port_send_async(port_info->sock_pair[0], message,
- __app_id, (local_port) ? local_port : "", local_trusted, bi_dir);
+ (local_port) ? local_port : "", local_trusted, bi_dir);
} else {
bus_name = port_info->encoded_bus_name;