revert it due to dlopen error
[sdk/target/sdbd.git] / src / socket_loopback_server.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
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 // libs/cutils/socket_loopback_server.c
17
18 #include "sockets.h"
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <stddef.h>
26
27 #define LISTEN_BACKLOG 4
28 #define LOOPBACK_UP 1
29 #define LOOPBACK_DOWN 0
30
31 #ifndef HAVE_WINSOCK
32 #include <sys/socket.h>
33 #include <sys/select.h>
34 #include <sys/types.h>
35 #include <netinet/in.h>
36 #include <sys/ioctl.h>
37 #include <net/if.h>
38 #include <arpa/inet.h>
39 #endif
40 #include "sysdeps.h"
41
42 int get_loopback_status(void) {
43
44     int           s;
45     struct ifconf ifc;
46     struct ifreq *ifr;
47     int           ifcnt;
48     char          buf[1024];
49     int i;
50
51     s = socket(AF_INET, SOCK_DGRAM, 0);
52     if(s < 0)
53     {
54         perror("socket");
55         return LOOPBACK_DOWN;
56     }
57
58     // query available interfaces
59     ifc.ifc_len = sizeof(buf);
60     ifc.ifc_buf = buf;
61     if(ioctl(s, SIOCGIFCONF, &ifc) < 0)
62     {
63         perror("ioctl(SIOCGIFCONF)");
64         sdb_close(s);
65         return LOOPBACK_DOWN;
66     }
67
68     // iterate the list of interfaces
69     ifr = ifc.ifc_req;
70     ifcnt = ifc.ifc_len / sizeof(struct ifreq);
71     for(i = 0; i < ifcnt; i++)
72     {
73         struct sockaddr_in *addr;
74         addr = (struct sockaddr_in *)&ifr->ifr_addr;
75
76         if (ntohl(addr->sin_addr.s_addr) == INADDR_LOOPBACK)
77         {
78             sdb_close(s);
79             return LOOPBACK_UP;
80         }
81     }
82     sdb_close(s);
83     return LOOPBACK_DOWN;
84 }
85
86 /* open listen() port on loopback interface */
87 int socket_loopback_server(int port, int type)
88 {
89     struct sockaddr_in addr;
90     int s, n;
91     int cnt_max = 30;
92
93     /* tizen specific */
94     // check the loopback interface has been up in 30 sec
95     while(cnt_max > 0) {
96         if(get_loopback_status() == LOOPBACK_DOWN) {
97             cnt_max--;
98             sdb_sleep_ms(1000);
99         }
100         else {
101             break;
102         }
103     }
104     memset(&addr, 0, sizeof(addr));
105     addr.sin_family = AF_INET;
106     addr.sin_port = htons(port);
107
108     if(cnt_max ==0) {
109         addr.sin_addr.s_addr = htonl(INADDR_ANY);
110     } else {
111         addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
112     }
113     s = socket(AF_INET, type, 0);
114     if(s < 0) {
115         return -1;
116     }
117
118     n = 1;
119     if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) < 0) {
120         sdb_close(s);
121         return -1;
122     }
123
124     if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
125         sdb_close(s);
126         return -1;
127     }
128
129     if (type == SOCK_STREAM) {
130         int ret;
131
132         ret = listen(s, LISTEN_BACKLOG);
133
134         if (ret < 0) {
135             sdb_close(s);
136             return -1;
137         }
138     }
139
140     return s;
141 }
142