RSA sync with private
[platform/core/messaging/msg-service.git] / utils / MsgIpcSocket.cpp
1 /*
2 * Copyright 2012  Samsung Electronics Co., Ltd
3 *
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *    http://www.tizenopensource.org/license
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <sys/socket.h>
18 #include <sys/un.h>
19 #include <sys/ioctl.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22
23 #include <errno.h>
24 #include <unistd.h>
25 #include <errno.h>
26
27 #include "MsgDebug.h"
28 #include "MsgException.h"
29 #include "MsgIpcSocket.h"
30
31
32 /*==================================================================================================
33                                      IMPLEMENTATION OF MsgIpcClientSocket - Member Functions
34 ==================================================================================================*/
35 MsgIpcClientSocket::MsgIpcClientSocket() : sockfd(-1), remotefd(-1), maxfd(-1)
36 {
37         FD_ZERO(&fds);
38 }
39
40
41 msg_error_t MsgIpcClientSocket::connect(const char* path)
42 {
43         MSG_BEGIN();
44
45         if (!path || strlen(path) > strlen(MSG_SOCKET_PATH)) {
46                 THROW(MsgException::IPC_ERROR, "path is null");
47         }
48
49         sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
50
51         if (sockfd < 0) {
52                 THROW(MsgException::IPC_ERROR,"socket not opened %s",strerror(errno));
53         }
54
55         struct sockaddr_un serverSA = {0, };
56         serverSA.sun_family = AF_UNIX;
57
58         memset(serverSA.sun_path, 0x00, sizeof(serverSA.sun_path));
59         strncpy(serverSA.sun_path, path, sizeof(serverSA.sun_path)-1);  /* // "./socket" */
60
61         int len = strlen(serverSA.sun_path) + sizeof(serverSA.sun_family);
62
63         if (::connect(sockfd, (struct sockaddr *)&serverSA, len) == CUSTOM_SOCKET_ERROR) {
64                 THROW(MsgException::IPC_ERROR,"cannot connect server %s", strerror(errno));
65         }
66
67         /* add fd for select() */
68         addfd(sockfd);
69
70         /* read remote fd for reg func */
71         char *rfd = NULL;
72         AutoPtr<char> wrap(&rfd);
73         unsigned int rlen;
74
75         read(&rfd, &rlen);
76
77         if (rfd == NULL) {
78                 THROW(MsgException::IPC_ERROR,"rfd is NULL %s", strerror(errno));
79         }
80
81         memcpy(&remotefd, rfd, sizeof(rlen));
82
83         MSG_DEBUG("Connected: client fd [%d] <----> remote fd [%d]", sockfd, remotefd);
84
85         MSG_END();
86
87         return MSG_SUCCESS;
88 }
89
90
91 msg_error_t MsgIpcClientSocket::close()
92 {
93         if (sockfd < 0) {
94                 MSG_FATAL("Client socket is not opened (check if you call close twice by accident) [%d]", sockfd);
95                 return MSG_ERR_UNKNOWN;
96         }
97
98         /* it means that client is going to close the connection.*/
99         int cmd = CLOSE_CONNECTION_BY_USER;
100         int len = sizeof(cmd);
101
102         char cmdbuf[len];
103         bzero(cmdbuf, len);
104         memcpy(cmdbuf, &cmd, len);
105
106         ::close(sockfd);
107         sockfd = CUSTOM_SOCKET_ERROR;
108
109         return MSG_SUCCESS;
110 }
111
112 void MsgIpcClientSocket::addfd(int fd)
113 {
114         MSG_DEBUG("%d added", fd);
115         FD_SET(fd, &fds);
116         if (fd > maxfd)
117                 maxfd = fd;
118 }
119
120 int MsgIpcClientSocket::writen (const char *buf, unsigned int len)
121 {
122         unsigned int nleft;
123         int nwrite;
124
125         nleft = len;
126         while (nleft > 0) {
127                 nwrite = ::write(sockfd, (const void*) buf, nleft);
128                 if (nwrite < 0) {
129                         MSG_FATAL("writen: sockfd [%d] error [%s]",  sockfd, strerror(errno));
130                         return nwrite;
131                 } else if (nwrite == 0) {
132                         break;
133                 }
134
135                 nleft -= nwrite;
136                 buf += nwrite;
137         }
138         return (len-nleft);
139 }
140
141 int MsgIpcClientSocket::write(const char* buf, unsigned int len)
142 {
143         if (sockfd < 0) {
144                 MSG_FATAL("sockfd is not opened [%d]", sockfd);
145                 return CUSTOM_SOCKET_ERROR;
146         }
147
148         if (!buf || len == 0) {
149                 MSG_FATAL("buf[%p]      and len[%d] MUST NOT NULL", buf, len);
150                 return CUSTOM_SOCKET_ERROR;
151         }
152
153         /* send the data size first */
154         int n = writen((const char*)&len, sizeof(len));
155         if (n != sizeof(len)) {
156                 MSG_FATAL("WARNING: write header_size[%d] not matched [%d]", n, sizeof(len));
157                 return CUSTOM_SOCKET_ERROR;
158         }
159
160         /* send the data in subsequence */
161         n = writen(buf, len);
162         if ((unsigned int)n != len) {
163                 MSG_FATAL("WARNING: write data_size[%d] not matched [%d]", n, len);
164                 return CUSTOM_SOCKET_ERROR;
165         }
166
167         return len;
168 }
169
170 int MsgIpcClientSocket::readn( char *buf, unsigned int len )
171 {
172         unsigned int nleft;
173         int nread;
174
175         nleft = len;
176         while (nleft > 0) {
177                 nread = ::read(sockfd, (void*) buf, nleft);
178                 if (nread < 0) {
179                         MSG_FATAL("WARNING read value %d: %s", nread, strerror(errno));
180                         return nread;
181                 } else if( nread == 0 ) {
182                         break;
183                 }
184
185                 nleft -= nread;
186                 buf += nread;
187         }
188
189         return (len-nleft);
190 }
191
192
193 /* what if the buf is shorter than data? */
194 int MsgIpcClientSocket::read(char** buf, unsigned int* len)
195 {
196         if (sockfd < 0) {
197                 MSG_FATAL("socket is not opened [%d]", sockfd);
198                 return CUSTOM_SOCKET_ERROR;
199         }
200
201         if (!buf || !len) {
202                 MSG_FATAL("rbuf and rlen MUST NOT NULL");
203                 return CUSTOM_SOCKET_ERROR;
204         }
205
206         /* read the data size first */
207         int n = readn((char*) len, sizeof(int));
208         if (n == CLOSE_CONNECTION_BY_SIGNAL) { /* if msgfw gets down, it signals to all IPC clients */
209                 MSG_FATAL("sockfd [%d] CLOSE_CONNECTION_BY_SIGNAL", sockfd);
210                 return n;
211         } else if (n != sizeof(int)) {
212                 MSG_FATAL("WARNING: read header_size[%d] not matched [%d]", n, sizeof(int));
213                 return CUSTOM_SOCKET_ERROR;
214         }
215
216         /*  read the data in subsequence */
217         unsigned int ulen = (unsigned int)*len;
218         *buf = new char[ulen];
219         bzero(*buf, ulen);
220         n = readn(*buf, ulen);
221
222         if ((unsigned int)n !=  ulen) {
223                 MSG_FATAL("WARNING: read data_size [%d] not matched [%d]", n, ulen);
224                 return CUSTOM_SOCKET_ERROR;
225         }
226
227         return n;
228 }
229
230
231 /*==================================================================================================
232                                      IMPLEMENTATION OF MsgIpcServerSocket - Member Functions
233 ==================================================================================================*/
234 MsgIpcServerSocket::MsgIpcServerSocket() : sockfd(-1), maxfd(-1)
235 {
236         FD_ZERO(&fds);
237 }
238
239 void MsgIpcServerSocket::addfd(int fd)
240 {
241         MSG_DEBUG("%d added", fd);
242         FD_SET(fd, &fds);
243
244         std::map<int, int>::iterator it = mapFds.find(fd);
245         if (it != mapFds.end())
246                 MSG_FATAL("Duplicate FD %d", fd);
247         else
248                 mapFds[fd] = fd;
249
250         if (fd > maxfd)
251                 maxfd = fd;
252 }
253
254 msg_error_t MsgIpcServerSocket::open(const char* path)
255 {
256         MSG_BEGIN();
257
258         if (!path || strlen(path) > strlen(MSG_SOCKET_PATH)) {
259                 MSG_FATAL("path is null");
260                 return MSG_ERR_INVALID_PARAMETER;
261         }
262
263         if (sockfd != CUSTOM_SOCKET_ERROR) {
264                 MSG_FATAL("WARNING: server_socket already opened %d at %p", sockfd,  &sockfd);
265                 return MSG_ERR_UNKNOWN;
266         }
267
268         sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
269
270         if (sockfd == CUSTOM_SOCKET_ERROR) {
271                 MSG_FATAL("socket failed: %s", strerror(errno));
272                 return MSG_ERR_UNKNOWN;
273         }
274
275         MSG_DEBUG("server_socket(%p) opened : %d", &sockfd, sockfd);
276
277         struct sockaddr_un local = {0, };
278
279         local.sun_family = AF_UNIX;
280         memset(local.sun_path, 0x00, sizeof(local.sun_path));
281         strncpy(local.sun_path, path, sizeof(local.sun_path)-1);
282
283         unlink(local.sun_path);
284
285         int len = strlen(local.sun_path) + sizeof(local.sun_family);
286
287         if (bind(sockfd, (struct sockaddr *)&local, len) == CUSTOM_SOCKET_ERROR) {
288                 MSG_FATAL("bind: %s", strerror(errno));
289                 return MSG_ERR_UNKNOWN;
290         }
291
292         /**
293          * determine permission of socket file
294          *
295          *  - S_IRWXU : for user, allow read and write and execute
296          *  - S_IRWXG : for group, allow read and write and execute
297          *  - S_IRWXO : for other, allow read and write and execute
298          *
299          *  - S_IRUSR, S_IWUSR, S_IXUSR : for user, allow only read, write, execute respectively
300          *  - S_IRGRP, S_IWGRP, S_IXGRP : for group, allow only read, write, execute respectively
301          *  - S_IROTH, S_IWOTH, S_IXOTH : for other, allow only read, write, execute respectively
302          */
303         mode_t sock_mode = (S_IRWXU | S_IRWXG | S_IRWXO); /* has 777 permission */
304
305         if (chmod(path, sock_mode) == CUSTOM_SOCKET_ERROR) {
306                 MSG_FATAL("chmod: %s", strerror(errno));
307                 return MSG_ERR_UNKNOWN;
308         }
309
310         if (listen(sockfd, CUSTOM_SOCKET_BACKLOG) == CUSTOM_SOCKET_ERROR) {
311                 MSG_FATAL("listen: %s", strerror(errno));
312                 return MSG_ERR_UNKNOWN;
313         }
314
315         addfd(sockfd);
316
317         MSG_END();
318
319         return MSG_SUCCESS;
320 }
321
322 msg_error_t MsgIpcServerSocket::accept()
323 {
324         MSG_BEGIN();
325
326         if (sockfd == CUSTOM_SOCKET_ERROR) {
327                 MSG_FATAL("server_socket not init");
328                 return MSG_ERR_UNKNOWN;
329         }
330
331         struct sockaddr_un remote;
332
333         int t = sizeof(remote);
334         int fd = ::accept(sockfd, (struct sockaddr *)&remote, (socklen_t*) &t);
335         if (fd < 0) {
336                 MSG_FATAL("accept: %s", strerror(errno));
337                 return MSG_ERR_UNKNOWN;
338         }
339
340         addfd(fd);
341         MSG_DEBUG("%d is added", fd);
342
343         /* write the registerd fd */
344         write(fd, (const char*) &fd, sizeof(fd));
345
346         MSG_END();
347
348         return MSG_SUCCESS;
349 }
350
351 void MsgIpcServerSocket::close(int fd)
352 {
353         MSG_BEGIN();
354
355         if (sockfd == CUSTOM_SOCKET_ERROR) {
356                 MSG_FATAL("server_socket not init");
357                 return;
358         }
359
360         MSG_DEBUG("%d to be removed", fd);
361         FD_CLR(fd, &fds);
362
363         std::map<int, int>::iterator it = mapFds.find(fd);
364         if (it == mapFds.end())
365                 MSG_FATAL("No FD %d", fd);
366         else
367                 mapFds.erase(it);
368
369         if (fd == maxfd) {
370                 int newmax = 0;
371                 for (it = mapFds.begin() ; it != mapFds.end() ; it++)
372                         newmax = (it->second > newmax )? it->second : newmax;
373                 maxfd = newmax;
374         }
375         MSG_DEBUG("fd %d removal done", fd);
376         ::close(fd);
377
378         MSG_END();
379 }
380
381 int MsgIpcServerSocket::readn( int fd, char *buf, unsigned int len )
382 {
383         size_t nleft;
384         int nread;
385
386         nleft = (size_t)len;
387         while (nleft > 0) {
388                 nread = ::read(fd, (void*)buf, nleft);
389                 if (nread < 0) {
390                         MSG_FATAL("read: %s", strerror(errno));
391                         return nread;
392                 }
393                 else if (nread == 0)
394                         break;
395
396                 nleft -= nread;
397                 buf += nread;
398         }
399         return (len-nleft);
400 }
401
402 int MsgIpcServerSocket::read(int fd, char** buf, int* len )
403 {
404         if (sockfd == CUSTOM_SOCKET_ERROR) {
405                 MSG_FATAL("server_socket(%p) is not initd %d", &sockfd, sockfd);
406                 return CUSTOM_SOCKET_ERROR;
407         }
408
409         if (!buf || !len) {
410                 MSG_FATAL("buf[%p] and len[%p] MUST NOT NULL", buf, len);
411                 return CUSTOM_SOCKET_ERROR;
412         }
413
414         /* read the data size first */
415         int n = readn(fd, (char*) len, sizeof(int));
416
417         if (n == CLOSE_CONNECTION_BY_SIGNAL) {
418                 MSG_FATAL("fd %d CLOSE_CONNECTION_BY_SIGNAL", fd);
419                 return n;
420         }
421
422         else if (n != sizeof(int)) {
423                 MSG_FATAL("readn %d(%d)", n, sizeof(int));
424                 return CUSTOM_SOCKET_ERROR;
425         }
426
427         MSG_DEBUG("MsgLen %d", *len);
428         if (*len == CLOSE_CONNECTION_BY_USER)
429                 return *len;
430
431         /* read the data in subsequence */
432         if (*len > 0) {
433                 unsigned int ulen = (unsigned int)*len;
434                 *buf = new char[ulen+1];
435                 bzero(*buf, ulen+1);
436                 n = readn(fd, *buf, ulen);
437
438                 if ((unsigned int)n != ulen) {
439                         MSG_FATAL("WARNING: read data_size [%d] not matched [%d]", n, ulen);
440                         return CUSTOM_SOCKET_ERROR;
441                 }
442         }
443
444         return n;
445 }
446
447 int MsgIpcServerSocket::writen(int fd, const char *buf, unsigned int len)
448 {
449         unsigned int nleft;
450         int nwrite;
451
452         nleft = len;
453
454         while (nleft > 0) {
455                 /*  MSG_NOSIGNAL to prevent SIGPIPE Error */
456                 /*  MSG_DONTWAIT to avoid socket block */
457                 nwrite = ::send(fd, (const void*) buf, nleft, MSG_NOSIGNAL|MSG_DONTWAIT);
458
459                 if (nwrite < 0) {
460                         MSG_FATAL("write: %s", strerror(errno));
461                         return nwrite;
462                 } else if (nwrite == 0) { /* Nothing is send. */
463                         break;
464                 } else {
465                         nleft -= nwrite;
466                         buf += nwrite;
467                 }
468         }
469
470         return (len-nleft);
471 }
472
473
474 int MsgIpcServerSocket::write(int fd, const char* buf, unsigned int len)
475 {
476         MSG_BEGIN();
477
478         if (!buf || len <= 0) {
479                 MSG_FATAL("buf [%p] and len [%d] MUST NOT NULL", buf, len);
480                 return CUSTOM_SOCKET_ERROR;
481         }
482
483         MSG_DEBUG("for debug - fd : [%d], buf : [%p], len : [%d]", fd, buf, len);
484
485         /* send the data size first */
486         int n = writen(fd, (const char*)&len, sizeof(len));
487
488         if (n != sizeof(len)) {
489                 MSG_FATAL("WARNING: write header_size[%d] not matched [%d]", n, sizeof(len));
490                 return CUSTOM_SOCKET_ERROR;
491         }
492
493         /*  send the data in subsequence */
494         n = writen(fd, buf, len);
495
496         MSG_DEBUG("Writing %d bytes", n);
497
498         if ((unsigned int)n != len) {
499                 MSG_FATAL("Written byte (%d) is not matched to input byte (%d)", n, len);
500                 return CUSTOM_SOCKET_ERROR;
501         }
502
503         MSG_END();
504
505         return len;
506 }