1 /**************************************************************************/
2 /* ---------------------------------------------------------------------- */
3 /* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
5 /* Universidad de Cantabria, SPAIN */
6 /* University of York, UK */
7 /* Scuola Superiore Sant'Anna, ITALY */
8 /* Kaiserslautern University, GERMANY */
9 /* Univ. Politécnica Valencia, SPAIN */
10 /* Czech Technical University in Prague, CZECH REPUBLIC */
12 /* Thales Communication S.A. FRANCE */
13 /* Visual Tools S.A. SPAIN */
14 /* Rapita Systems Ltd UK */
17 /* See http://www.frescor.org for a link to partners' websites */
19 /* FRESCOR project (FP6/2005/IST/5-034026) is funded */
20 /* in part by the European Union Sixth Framework Programme */
21 /* The European Union is not liable of any use that may be */
22 /* made of this code. */
25 /* This file is part of FORB (Frescor Object Request Broker) */
27 /* FORB is free software; you can redistribute it and/or modify it */
28 /* under terms of the GNU General Public License as published by the */
29 /* Free Software Foundation; either version 2, or (at your option) any */
30 /* later version. FORB is distributed in the hope that it will be */
31 /* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
32 /* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
33 /* General Public License for more details. You should have received a */
34 /* copy of the GNU General Public License along with FORB; see file */
35 /* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
36 /* Cambridge, MA 02139, USA. */
38 /* As a special exception, including FORB header files in a file, */
39 /* instantiating FORB generics or templates, or linking other files */
40 /* with FORB objects to produce an executable application, does not */
41 /* by itself cause the resulting executable application to be covered */
42 /* by the GNU General Public License. This exception does not */
43 /* however invalidate any other reasons why the executable file might be */
44 /* covered by the GNU Public License. */
45 /**************************************************************************/
49 #include <forb/proto_unix.h>
51 #include <sys/socket.h>
52 #include <sys/types.h>
55 typedef struct sockaddr_un unix_addr_t;
57 /** UNIX protocol data for ports. */
63 static struct unix_port*
64 peer_to_uport(forb_peer_t *peer) { return peer->port->proto_priv; }
67 unix_server_to_addr(unix_addr_t *addr, const forb_server_id *server)
70 addr->sun_family = AF_UNIX;
71 sprintf(addr->sun_path, "/tmp/forb-%s",
72 forb_uuid_to_string(str, (forb_uuid_t*)server->uuid, sizeof(str)));
76 unix_send(forb_peer_t *peer, const void *buf, size_t len)
79 struct unix_port *p = peer_to_uport(peer);
80 //printf("send to %s\n", c->addr.sun_path);
81 unix_server_to_addr(&addr, &peer->server_id);
82 return sendto(p->socket, buf, len, 0,
83 (struct sockaddr*)&addr, sizeof(addr));
87 unix_recv(forb_port_t *port, void *buf, size_t len)
89 struct unix_port *p = port->proto_priv;
90 return recv(p->socket, buf, len, 0);
94 unix_port_destroy(forb_port_t * port)
96 struct unix_port *pd = port->proto_priv;
98 socklen_t len = sizeof(addr);
99 getsockname(pd->socket, (struct sockaddr*)&addr, &len);
100 if (addr.sun_family == AF_UNIX)
101 unlink(addr.sun_path);
108 unix_broadcast(forb_port_t *port, const void *buf, size_t len)
110 struct unix_port *p = port->proto_priv;
112 struct dirent *dirent;
117 dir = opendir("/tmp");
118 if (!dir) return -errno;
120 addr.sun_family = AF_UNIX;
122 while ((dirent = readdir(dir))) {
124 #ifdef _DIRENT_HAVE_D_TYPE
125 (dirent->d_type == DT_SOCK ||
126 dirent->d_type == DT_UNKNOWN) &&
128 (strncmp(dirent->d_name, "forb-", 5) == 0);
130 /* printf("d_name=%s d_type=%d (%d)\n", dirent->d_name, dirent->d_type, DT_SOCK); */
133 strcpy(addr.sun_path, "/tmp/");
134 strncat(addr.sun_path, dirent->d_name, sizeof(addr.sun_path));
135 /* printf("Broadcasting to %s\n", addr.sun_path); */
136 ret = sendto(p->socket, buf, len, 0,
137 (struct sockaddr*)&addr, sizeof(addr));
138 /* We do not care about errors in brodcasts -
139 * the socket may nomore be active */
143 /* perror("unix_broadcast"); */
158 static const forb_proto_t proto_unix = {
159 .hello_interval = 40 /* seconds */,
160 .port_destroy = unix_port_destroy,
161 .peer_destroy = NULL,
164 .broadcast = unix_broadcast,
165 /* We do not need the following functions, sice the address
166 * can be derived from server_id */
167 .serialize_addr = NULL,
168 .deserialize_addr = NULL,
172 * Initializes UNIX protocol port.
174 * @param port Port to initialize.
175 * @param server Server this port belongs to.
177 * @return Zero on success, -1 on error and errno is set
181 forb_unix_port_init(forb_port_t *port, const forb_server_id *server)
185 struct unix_port *pd;
187 pd = forb_malloc(sizeof(*pd));
191 pd->socket = socket(PF_UNIX, SOCK_DGRAM, 0);
192 if (pd->socket == -1) goto err1;
194 unix_server_to_addr(&pd->addr, server);
195 /* unlink(pd->addr.sun_path); */ /* TODO: What to do when the socket already exist? */
196 ret = bind(pd->socket, (struct sockaddr*)&pd->addr, sizeof(pd->addr));
197 if (ret == -1) goto err;
199 port->proto = &proto_unix;
200 port->proto_priv = pd;