/[pdpsoft]/trunk/grid-mw-security/ees/src/app/main.c
ViewVC logotype

Contents of /trunk/grid-mw-security/ees/src/app/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1589 - (show annotations) (download) (as text)
Wed Mar 24 16:09:58 2010 UTC (12 years, 6 months ago) by aramv
File MIME type: text/x-chdr
File size: 9537 byte(s)
Doing something with select and xacml_server_set_fd()
1 #define _MULTI_THREADED
2 #define NUM_THREADS 2
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <pthread.h>
7
8 #include <unistd.h>
9 #include <netinet/in.h>
10 #include <sys/types.h>
11 #include <sys/socket.h>
12 #include <string.h>
13 #include <netdb.h>
14 #include <arpa/inet.h>
15
16 #include "ees_eics.h"
17 #include "xacml.h"
18 #include "xacml_server.h"
19 #include "eef_library.h"
20
21 #define PORT 1234
22 #define BACKLOG 10
23
24 typedef enum xacml_server_state_wrapper_s {
25 READY,
26 BUSY
27 } xacml_server_state_wrapper_t;
28
29 typedef struct xacml_server_wrapper_s {
30 xacml_server_state_wrapper_t state;
31 xacml_server_t server;
32 } xacml_server_wrapper_t;
33
34 pthread_t threads[NUM_THREADS]; /* thread pool */
35 xacml_server_wrapper_t* xacml_threads[NUM_THREADS]; /* xacml 'server' pool */
36 char* config_file_path; /* config file path */
37 int listen_socket;
38 int fdmax;
39 fd_set master;
40 fd_set read_fds;
41 struct timeval timeout;
42
43 int process_xacml(int);
44 xacml_server_wrapper_t* make_xacml_server(void);
45 xacml_server_wrapper_t* get_ready_xacml_server(void);
46 char *get_ip_str(const struct sockaddr *sa);
47 void signal_handler(int sig);
48 int bind_socket(void);
49 EES_RC ees_stop(void);
50 EES_RC ees_start(void);
51 EES_RC ees_loop(void);
52 EES_RC add_dummy_aos_obligation(void);
53
54 xacml_server_wrapper_t* make_xacml_server(void){
55 xacml_server_wrapper_t* server_wrapper;
56 xacml_server_t server;
57 xacml_init(); /* if you look at the code, you'll see this function is empty */
58 if(xacml_server_init(&server, ees_xacml_authorize, NULL) == XACML_RESULT_SUCCESS){
59 /* Set the I/O handler object */
60 /* xacml_server_set_io_descriptor(server, &xacml_io_ssl_descriptor); */
61 /* start server and block further execution */
62 if((server_wrapper = calloc(1, sizeof(xacml_server_wrapper_t)))){
63 server_wrapper->state = READY;
64 server_wrapper->server = server;
65 }
66 printf("Server initialized at: %p\n", server);
67 }
68 return server_wrapper;
69 }
70
71 xacml_server_wrapper_t* get_ready_xacml_server(void){
72 int i;
73 xacml_server_wrapper_t* server_wrapper = NULL;
74 xacml_server_t server;
75 for(i = 0; i < NUM_THREADS; i++){
76 server_wrapper = (xacml_server_wrapper_t*) xacml_threads[i];
77 if(server_wrapper->state == READY){
78 break;
79 }
80 }
81 return server_wrapper;
82 }
83
84 /**
85 Convert a struct sockaddr address to a string, IPv4 and IPv6.
86 Adapted from: http://beej.us/guide/bgnet/output/html/multipage/inet_ntopman.html
87 */
88 char *get_ip_str(const struct sockaddr *sa){
89 char* s;
90 switch(sa->sa_family) {
91 case AF_INET:
92 if((s = calloc(1, INET6_ADDRSTRLEN))){
93 inet_ntop(AF_INET, &(((const struct sockaddr_in *)sa)->sin_addr), s, INET6_ADDRSTRLEN);
94 }
95 break;
96 case AF_INET6:
97 if((s = calloc(1, INET_ADDRSTRLEN))){
98 inet_ntop(AF_INET6, &(((const struct sockaddr_in6 *)sa)->sin6_addr), s, INET_ADDRSTRLEN);
99 }
100 break;
101 default:
102 strncpy(s, "Unknown", strlen("Unknown")+1);
103 }
104 return s;
105 }
106
107 int bind_socket(void){
108 int sockfd; // listen on sock_fd, new connection on new_fd
109 struct addrinfo hints, *servinfo, *p;
110 int reuse_addr=1;
111 char port_str[7];
112 int rv;
113
114 sprintf(port_str, "%i", PORT);
115
116 memset(&hints, 0, sizeof hints);
117 hints.ai_family = AF_UNSPEC;
118 hints.ai_socktype = SOCK_STREAM;
119 hints.ai_flags = AI_PASSIVE; // use my IP
120
121 if ((rv = getaddrinfo(NULL, port_str, &hints, &servinfo)) != 0) {
122 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
123 return 1;
124 }
125
126 // loop through all the results and bind to the first we can
127 for(p = servinfo; p != NULL; p = p->ai_next) {
128 if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
129 perror("server: socket");
130 continue;
131 }
132 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr)) == -1) {
133 perror("setsockopt");
134 }
135 if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
136 close(sockfd);
137 perror("server: bind");
138 continue;
139 }
140
141 break;
142 }
143
144 if (p == NULL) {
145 fprintf(stderr, "server: failed to bind\n");
146 return 2;
147 }
148 printf("Bound to: %s:%i\n", get_ip_str(servinfo->ai_addr), PORT);
149 freeaddrinfo(servinfo); // all done with this structure
150 return sockfd;
151 }
152
153 void signal_handler(int sig){
154 switch(sig){
155 case SIGHUP:
156 eef_log(LOG_NOTICE, "Got SIGHUP - restart \n");
157 printf("Got SIGHUP - restart \n");
158 ees_stop();
159 ees_start();
160 ees_loop();
161 break;
162 case SIGTERM:
163 eef_log(LOG_NOTICE, "Got SIGTERM - shutting down\n");
164 printf("Got SIGTERM - shutting down\n");
165 ees_stop();
166 exit(0);
167 break;
168 }
169 }
170
171 EES_RC add_dummy_aos_obligation(void){
172 aos_context_t* _context;
173 aos_attribute_t *_uid, *_gid;
174
175 char* _uid_str = "1234";
176 char* _gid_str = "1234";
177
178 /*fill aos */
179 _uid = createAttribute();
180 _gid = createAttribute();
181
182 setAttributeId(_uid, "posix-uid");
183 setAttributeValue(_uid, _uid_str, strlen(_uid_str));
184 setAttributeId(_gid, "posix-gid");
185 setAttributeValue(_gid, _gid_str, strlen(_gid_str));
186
187 if((_context = createContext(OBLIGATION)) != NULL){
188 setContextObligationId(_context, "uidgid");
189
190 addAttribute(_context, _uid);
191 addAttribute(_context, _gid);
192
193 addContext(_context);
194 }
195 return EES_SUCCESS;
196 }
197
198 EES_RC ees_start(void){
199 long t; /* thread iterator */
200 /* reuse this part when implementing SIGHUP */
201 printf("Parsing config file %s\n", config_file_path);
202 if(EEF_Init(config_file_path, NULL, 0, NULL) == EES_FAILURE){
203 eef_log(LOG_ERR, "Failed to parse config file (%s), exiting...", config_file_path);
204 } else {
205 aos_dump_argslist();
206 aos_start_threading();
207 /*process_xacml(PORT);*/
208 /* start threading */
209 for(t=0; t < NUM_THREADS; t++){
210 printf("Creating thread %li!\n", t);
211 /*rc = pthread_create(&threads[t], NULL, (void*)(void*) EEF_Run, (void*)(t));*/
212 /*rc = pthread_create(&threads[t], NULL, (void*)(void*) process_xacml, (void*)(PORT));*/
213 /*rc = pthread_join(threads[t], &status);*/
214 xacml_threads[t] = make_xacml_server();
215
216 /**//*Fire up SAML2-XACML2 */
217 /**//*process_xacml(PORT);*/
218
219 }
220 }
221 return EES_SUCCESS;
222 }
223
224 EES_RC ees_loop(void){
225 int i, j;
226 socklen_t addrlen;
227 struct sockaddr_storage remoteaddr;
228 int newfd;
229 int nbytes;
230 char buf[256];
231 xacml_server_wrapper_t* ready_server_wrapper = NULL;
232 while(1){
233 read_fds = master;
234 if(select(fdmax+1, &read_fds, NULL, NULL, NULL) >= 0){
235 for(i = 0; i <= fdmax; i++){
236 if(FD_ISSET(i, &read_fds)){
237 /*printf("We got one!\n");*/
238 if(i == listen_socket){
239 ready_server_wrapper = get_ready_xacml_server();
240 // handle new connection
241 printf("Got new connection\n");
242 addrlen = sizeof(remoteaddr);
243 /*newfd = accept(listen_socket, (struct sockaddr*) &remoteaddr, &addrlen);*/
244 /*if(newfd == -1){*/
245 /*printf("Bug!\n");*/
246 /*} else {*/
247 FD_SET(newfd, &master);
248 if(newfd > fdmax){
249 fdmax = newfd;
250 }
251 printf("ees: new connection from %s on socket %d\n", get_ip_str((struct sockaddr*) &remoteaddr), newfd);
252 if(xacml_server_set_fd(ready_server_wrapper->server, newfd) == XACML_RESULT_SUCCESS){
253 xacml_server_start(ready_server_wrapper->server);
254 }
255
256 /*}*/
257 } else {
258 // handle data from connected client
259 if ((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) {
260 // got error or connection closed by client
261 if (nbytes == 0) {
262 // connection closed
263 printf("ees: socket %d hung up\n", i);
264 } else {
265 perror("recv");
266 }
267 close(i); // bye!
268 FD_CLR(i, &master); // remove from master set
269 } else {
270 // we got some data from a client
271 for(j = 0; j <= fdmax; j++) {
272 // send to everyone!
273 if (FD_ISSET(j, &master)) {
274 // except the listener and ourselves
275 if (j != listen_socket && j != i) {
276 if (send(j, buf, nbytes, 0) == -1) {
277 perror("send");
278 }
279 }
280 }
281 }
282 }
283 }
284 }
285 }
286 }
287 }
288 return EES_SUCCESS;
289 }
290
291 EES_RC ees_stop(void){
292 long t; /* thread iterator */
293 AOS_Clean();
294 EEF_Term();
295 for(t=0; t < NUM_THREADS; t++){
296 /*xacml_server_destroy(server);*/
297 printf("XACML service destroyed\n");
298 }
299 fflush(stdout);
300 fflush(stderr);
301 return EES_SUCCESS;
302 }
303
304 int main (int argc, char* argv[]){
305 int rc; /* return code from pthread functions */
306 void* status; /* thread join status */
307
308 if(argc > 1){
309 config_file_path = argv[1];
310 } else {
311 config_file_path = "examples/example_1.pdl";
312 }
313
314 listen_socket = bind_socket();
315 ees_start();
316
317 #if !ENABLE_DEBUG
318 EEF_Daemonize();
319 #endif
320
321 signal(SIGHUP, signal_handler); /* catch hangup signal */
322 signal(SIGTERM, signal_handler); /* catch kill signal */
323 FD_ZERO(&master);
324 FD_ZERO(&read_fds);
325
326 if(listen(listen_socket, BACKLOG) == 0){
327 printf("Ready.\n");
328 FD_SET(listen_socket, &master);
329 fdmax = listen_socket;
330 ees_loop();
331 } else {
332 eef_log(LOG_ERR, "Error listening: %s\n", strerror(errno));
333 }
334
335 printf("terminated!\n");
336
337 aos_dump_argslist();
338 /*pthread_exit(NULL);*/
339
340 return 0;
341 }
342

grid.support@nikhef.nl
ViewVC Help
Powered by ViewVC 1.1.28