Change default TON to unknown.
[framework/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         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, int len)
121 {
122         int nleft, nwrite;
123
124         nleft = len;
125         while (nleft > 0) {
126                 nwrite = ::write(sockfd, (const void*) buf, nleft);
127                 if (nwrite < 0) {
128                         MSG_FATAL("writen: sockfd [%d] error [%s]",  sockfd, strerror(errno));
129                         return nwrite;
130                 }
131                 else if (nwrite == 0)
132                         break;
133
134                 nleft -= nwrite;
135                 buf += nwrite;
136         }
137         return (len-nleft);
138 }
139
140 int MsgIpcClientSocket::write(const char* buf, int len)
141 {
142         if (sockfd < 0) {
143                 MSG_FATAL("sockfd is not opened [%d]", sockfd);
144                 return CUSTOM_SOCKET_ERROR;
145         }
146
147         if (!buf || len <= 0) {
148                 MSG_FATAL("buf[%p]      and len[%d] MUST NOT NULL", buf, len);
149                 return CUSTOM_SOCKET_ERROR;
150         }
151
152         /* send the data size first */
153         int n = writen((const char*)&len, sizeof(len));
154         if (n != sizeof(len)) {
155                 MSG_FATAL("WARNING: write header_size[%d] not matched [%d]", n, sizeof(len));
156                 return CUSTOM_SOCKET_ERROR;
157         }
158
159         /* send the data in subsequence */
160         n = writen(buf, len);
161         if (n != len) {
162                 MSG_FATAL("WARNING: write data_size[%d] not matched [%d]", n, len);
163                 return CUSTOM_SOCKET_ERROR;
164         }
165
166         return len;
167 }
168
169 int MsgIpcClientSocket::readn( char *buf, int len )
170 {
171         int nleft, nread;
172
173         nleft = len;
174         while (nleft > 0) {
175                 nread = ::read(sockfd, (void*) buf, nleft);
176                 if (nread < 0) {
177                         MSG_FATAL("WARNING read value %d: %s", nread, strerror(errno));
178                         return nread;
179                 }
180                 else if( nread == 0 )
181                         break;
182
183                 nleft -= nread;
184                 buf += nread;
185         }
186         return (len-nleft);
187 }
188
189
190 /* what if the buf is shorter than data? */
191 int MsgIpcClientSocket::read(char** buf, int* len)
192 {
193         if (sockfd < 0) {
194                 MSG_FATAL("socket is not opened [%d]", sockfd);
195                 return CUSTOM_SOCKET_ERROR;
196         }
197
198         if (!buf || !len) {
199                 MSG_FATAL("rbuf and rlen MUST NOT NULL");
200                 return CUSTOM_SOCKET_ERROR;
201         }
202
203         /* read the data size first */
204         int n = readn((char*) len, sizeof(int));
205         if (n == CLOSE_CONNECTION_BY_SIGNAL) { /* if msgfw gets down, it signals to all IPC clients */
206                 MSG_FATAL("sockfd [%d] CLOSE_CONNECTION_BY_SIGNAL", sockfd);
207                 return n;
208         }
209
210         else if (n != sizeof(int)) {
211                 MSG_FATAL("WARNING: read header_size[%d] not matched [%d]", n, sizeof(int));
212                 return CUSTOM_SOCKET_ERROR;
213         }
214
215         /*  read the data in subsequence */
216         if ((*len) > 0) {
217                 unsigned int ulen = (unsigned int)*len;
218                 *buf = new char[ulen+1];
219                 bzero(*buf, ulen+1);
220                 n = readn(*buf, ulen);
221
222                 if (n !=  ulen) {
223                         MSG_FATAL("WARNING: read data_size [%d] not matched [%d]", n, ulen);
224                         return CUSTOM_SOCKET_ERROR;
225                 }
226         }
227
228         return n;
229 }
230
231
232 /*==================================================================================================
233                                      IMPLEMENTATION OF MsgIpcServerSocket - Member Functions
234 ==================================================================================================*/
235 MsgIpcServerSocket::MsgIpcServerSocket() : sockfd(-1), maxfd(-1)
236 {
237         FD_ZERO(&fds);
238 }
239
240 void MsgIpcServerSocket::addfd(int fd)
241 {
242         MSG_DEBUG("%d added", fd);
243         FD_SET(fd, &fds);
244
245         std::map<int, int>::iterator it = mapFds.find(fd);
246         if (it != mapFds.end())
247                 MSG_FATAL("Duplicate FD %d", fd);
248         else
249                 mapFds[fd] = fd;
250
251         if (fd > maxfd)
252                 maxfd = fd;
253 }
254
255 msg_error_t MsgIpcServerSocket::open(const char* path)
256 {
257         MSG_BEGIN();
258
259         if (!path || strlen(path) > strlen(MSG_SOCKET_PATH)) {
260                 MSG_FATAL("path is null");
261                 return MSG_ERR_INVALID_PARAMETER;
262         }
263
264         if (sockfd != CUSTOM_SOCKET_ERROR) {
265                 MSG_FATAL("WARNING: server_socket already opened %d at %p", sockfd,  &sockfd);
266                 return MSG_ERR_UNKNOWN;
267         }
268
269         sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
270
271         if (sockfd == CUSTOM_SOCKET_ERROR) {
272                 MSG_FATAL("socket failed: %s", strerror(errno));
273                 return MSG_ERR_UNKNOWN;
274         }
275
276         MSG_DEBUG("server_socket(%p) opened : %d", &sockfd, sockfd);
277
278         struct sockaddr_un local = {0, };
279
280         local.sun_family = AF_UNIX;
281         memset(local.sun_path, 0x00, sizeof(local.sun_path));
282         strncpy(local.sun_path, path, sizeof(local.sun_path)-1);
283
284         unlink(local.sun_path);
285
286         int len = strlen(local.sun_path) + sizeof(local.sun_family);
287
288         if (bind(sockfd, (struct sockaddr *)&local, len) == CUSTOM_SOCKET_ERROR) {
289                 MSG_FATAL("bind: %s", strerror(errno));
290                 return MSG_ERR_UNKNOWN;
291         }
292
293         /**
294          * determine permission of socket file
295          *
296          *  - S_IRWXU : for user, allow read and write and execute
297          *  - S_IRWXG : for group, allow read and write and execute
298          *  - S_IRWXO : for other, allow read and write and execute
299          *
300          *  - S_IRUSR, S_IWUSR, S_IXUSR : for user, allow only read, write, execute respectively
301          *  - S_IRGRP, S_IWGRP, S_IXGRP : for group, allow only read, write, execute respectively
302          *  - S_IROTH, S_IWOTH, S_IXOTH : for other, allow only read, write, execute respectively
303          */
304         mode_t sock_mode = (S_IRWXU | S_IRWXG | S_IRWXO); /* has 777 permission */
305
306         if (chmod(path, sock_mode) == CUSTOM_SOCKET_ERROR) {
307                 MSG_FATAL("chmod: %s", strerror(errno));
308                 return MSG_ERR_UNKNOWN;
309         }
310
311         if (listen(sockfd, CUSTOM_SOCKET_BACKLOG) == CUSTOM_SOCKET_ERROR) {
312                 MSG_FATAL("listen: %s", strerror(errno));
313                 return MSG_ERR_UNKNOWN;
314         }
315
316         addfd(sockfd);
317
318         MSG_END();
319
320         return MSG_SUCCESS;
321 }
322
323 msg_error_t MsgIpcServerSocket::accept()
324 {
325         MSG_BEGIN();
326
327         if (sockfd == CUSTOM_SOCKET_ERROR) {
328                 MSG_FATAL("server_socket not init");
329                 return MSG_ERR_UNKNOWN;
330         }
331
332         struct sockaddr_un remote;
333
334         int t = sizeof(remote);
335         int fd = ::accept(sockfd, (struct sockaddr *)&remote, (socklen_t*) &t);
336         if (fd < 0) {
337                 MSG_FATAL("accept: %s", strerror(errno));
338                 return MSG_ERR_UNKNOWN;
339         }
340
341         addfd(fd);
342         MSG_DEBUG("%d is added", fd);
343
344         /* write the registerd fd */
345         write(fd, (const char*) &fd, sizeof(fd));
346
347         MSG_END();
348
349         return MSG_SUCCESS;
350 }
351
352 void MsgIpcServerSocket::close(int fd)
353 {
354         MSG_BEGIN();
355
356         if (sockfd == CUSTOM_SOCKET_ERROR) {
357                 MSG_FATAL("server_socket not init");
358                 return;
359         }
360
361         MSG_DEBUG("%d to be removed", fd);
362         FD_CLR(fd, &fds);
363
364         std::map<int, int>::iterator it = mapFds.find(fd);
365         if (it == mapFds.end())
366                 MSG_FATAL("No FD %d", fd);
367         else
368                 mapFds.erase(it);
369
370         if (fd == maxfd) {
371                 int newmax = 0;
372                 for (it = mapFds.begin() ; it != mapFds.end() ; it++)
373                         newmax = (it->second > newmax )? it->second : newmax;
374                 maxfd = newmax;
375         }
376         MSG_DEBUG("fd %d removal done", fd);
377         ::close(fd);
378
379         MSG_END();
380 }
381
382 int MsgIpcServerSocket::readn( int fd, char *buf, int len )
383 {
384         int nleft, nread;
385
386         nleft = 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         if ((*len) > 0) {
432                 /* read the data in subsequence */
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 (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, int len)
448 {
449         int nleft, nwrite;
450
451         nleft = len;
452
453         while (nleft > 0) {
454                 /*  MSG_NOSIGNAL to prevent SIGPIPE Error */
455                 /*  MSG_DONTWAIT to avoid socket block */
456                 nwrite = ::send(fd, (const void*) buf, nleft, MSG_NOSIGNAL|MSG_DONTWAIT);
457
458                 if (nwrite < 0) {
459                         MSG_FATAL("write: %s", strerror(errno));
460                         return nwrite;
461                 }
462                 else if (nwrite == 0) { /* Nothing is send. */
463                         break;
464                 }
465                 else {
466                         nleft -= nwrite;
467                         buf += nwrite;
468                 }
469         }
470
471         return (len-nleft);
472 }
473
474
475 int MsgIpcServerSocket::write(int fd, const char* buf, int len)
476 {
477         MSG_BEGIN();
478
479         if (!buf || len <= 0) {
480                 MSG_FATAL("buf [%p] and len [%d] MUST NOT NULL", buf, len);
481                 return CUSTOM_SOCKET_ERROR;
482         }
483
484         MSG_DEBUG("for debug - fd : [%d], buf : [%p], len : [%d]", fd, buf, len);
485
486         /* send the data size first */
487         int n = writen(fd, (const char*)&len, sizeof(len));
488
489         if (n != sizeof(len)) {
490                 MSG_FATAL("WARNING: write header_size[%d] not matched [%d]", n, sizeof(len));
491                 return CUSTOM_SOCKET_ERROR;
492         }
493
494         /*  send the data in subsequence */
495         n = writen(fd, buf, len);
496
497         MSG_DEBUG("Writing %d bytes", n);
498
499         if (n != len) {
500                 MSG_FATAL("Written byte (%d) is not matched to input byte (%d)", n, len);
501                 return CUSTOM_SOCKET_ERROR;
502         }
503
504         MSG_END();
505
506         return len;
507 }