2 rxpd_socket.c - regex policy daemon
5 2007, Christian Thaeter <ct@pipapo.org>
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 rxpd_socket_new_tcp4 (struct rxpd_base
* base
, const char* addr
, unsigned short port
)
27 struct rxpd_socket
* self
;
28 self
= rxpd_malloc (sizeof (struct rxpd_socket
));
32 llist_init (&self
->node
);
34 self
->fd
= socket (PF_INET
, SOCK_STREAM
, 0);
38 struct sockaddr_in listen_addr
;
39 memset (&listen_addr
, 0, sizeof (listen_addr
));
41 listen_addr
.sin_family
= AF_INET
;
44 if (inet_aton (addr
, &listen_addr
.sin_addr
) == 0)
48 listen_addr
.sin_addr
.s_addr
= INADDR_ANY
;
50 listen_addr
.sin_port
= htons(port
);
52 if (bind (self
->fd
, (struct sockaddr
*)&listen_addr
, sizeof (listen_addr
)) == -1)
56 if (setsockopt (self
->fd
, SOL_SOCKET
, SO_REUSEADDR
, &yes
, sizeof(int)) == -1)
59 if (listen (self
->fd
, 20) == -1)
62 self
->rxpd_socket_addr
= rxpd_socket_tcp4addr
;
64 self
->accepter
= NULL
;
65 llist_insert_tail (&base
->sockets
, &self
->node
);
67 rxpd_log (base
, LOG_INFO
, "Listening on tcp4:%d\n", port
);
71 rxpd_die ("failed creating socket\n");
72 /* free (self); rxpd_die never returns */
77 rxpd_socket_tcp4addr (struct rxpd_connection
* conn
, char* dst
, const char* pfx
, size_t size
)
79 struct sockaddr_in peer
;
80 socklen_t len
= sizeof (peer
);
81 getpeername (conn
->fd
, (struct sockaddr
*)&peer
, &len
);
84 addr
= inet_ntoa (peer
.sin_addr
);
85 if (sizeof (":tcp4:") + strlen (pfx
) + strlen (addr
) > size
)
89 strcat (dst
, ":tcp4:");
95 rxpd_socket_delete (struct rxpd_socket
* self
)
99 llist_unlink (&self
->node
);
106 rxpd_socket_join (struct rxpd_socket
* self
)
108 pth_join (self
->accepter
, NULL
);
109 self
->accepter
= NULL
;
114 rxpd_socket_spawn (struct rxpd_socket
* self
)
119 rxpd_die ("socket thread already spawned\n");
121 self
->accepter
= pth_spawn (PTH_ATTR_DEFAULT
, rxpd_socket_accept
, self
);
124 rxpd_die ("failed spawning thread\n");
130 rxpd_socket_cancel (struct rxpd_socket
* self
)
132 pth_cancel (self
->accepter
);
137 rxpd_socket_accept (void* ptr
)
139 struct rxpd_socket
* self
= ptr
;
141 pth_event_t ev
= pth_event (PTH_EVENT_FD
|PTH_UNTIL_FD_READABLE
, self
->fd
);
143 while (pth_wait (ev
))
145 int fd
= pth_accept (self
->fd
, NULL
, 0);
147 rxpd_die ("error accepting connection\n");
149 struct rxpd_connection
* conn
= rxpd_connection_new (self
, fd
);
153 if (rxpd_socket_tcp4addr (conn
, buf
, "", 511))
155 rxpd_log (self
->base
, LOG_INFO
, "incoming connection '%s'\n", buf
);
156 rxpd_connection_spawn (conn
);
159 rxpd_log (self
->base
, LOG_ERR
, "illegal hostname\n", buf
);
162 rxpd_log (NULL
, LOG_NOTICE
, "closed\n");