1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 #include <sys/socket.h>
7 #include <netinet/tcp.h>
12 #include <sys/ioctl.h>
14 #include <asm/byteorder.h>
19 #include <portals/api-support.h>
20 #include <portals/list.h>
21 #include <portals/lib-types.h>
22 #include <portals/socknal.h>
24 /* should get this from autoconf somehow */
26 #define PIDFILE_DIR "/var/run"
29 #define PROGNAME "acceptor"
31 void create_pidfile(char *name, int port)
36 snprintf(pidfile, sizeof(pidfile), "%s/%s-%d.pid",
37 PIDFILE_DIR, name, port);
39 if ((fp = fopen(pidfile, "w"))) {
40 fprintf(fp, "%d\n", getpid());
43 syslog(LOG_ERR, "%s: %s\n", pidfile,
48 int pidfile_exists(char *name, int port)
52 snprintf(pidfile, sizeof(pidfile), "%s/%s-%d.pid",
53 PIDFILE_DIR, name, port);
55 if (!access(pidfile, F_OK)) {
56 fprintf(stderr, "%s: exists, acceptor already running.\n",
64 parse_size (int *sizep, char *str)
69 switch (sscanf (str, "%d%1[gGmMkK]", &size, mod))
104 show_connection (int fd, __u32 net_ip)
106 struct hostent *h = gethostbyaddr ((char *)&net_ip, sizeof net_ip, AF_INET);
107 __u32 host_ip = ntohl (net_ip);
114 len = sizeof (txmem);
115 if (getsockopt (fd, SOL_SOCKET, SO_SNDBUF, &txmem, &len) != 0)
116 perror ("Cannot get write buffer size");
118 len = sizeof (rxmem);
119 if (getsockopt (fd, SOL_SOCKET, SO_RCVBUF, &rxmem, &len) != 0)
120 perror ("Cannot get read buffer size");
122 len = sizeof (nonagle);
123 if (getsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &nonagle, &len) != 0)
124 perror ("Cannot get nagle");
127 snprintf (host, sizeof(host), "%d.%d.%d.%d", (host_ip >> 24) & 0xff,
128 (host_ip >> 16) & 0xff, (host_ip >> 8) & 0xff, host_ip & 0xff);
130 snprintf (host, sizeof(host), "%s", h->h_name);
132 syslog (LOG_INFO, "Accepted host: %s snd: %d rcv %d nagle: %s\n",
133 host, txmem, rxmem, nonagle ? "disabled" : "enabled");
139 fprintf (stderr, "Usage: %s [-r recv_mem] [-s send_mem] [-n] [-N nal_id] port\n", myname);
143 int main(int argc, char **argv)
145 int o, fd, rc, port, pfd;
146 struct sockaddr_in srvaddr;
155 while ((c = getopt (argc, argv, "N:r:s:nli")) != -1)
159 if (parse_size (&rxmem, optarg) != 0 || rxmem < 0)
164 if (parse_size (&txmem, optarg) != 0 || txmem < 0)
181 if (parse_size(&nal, optarg) != 0 ||
182 nal < 0 || nal > NAL_MAX_NR)
194 port = atol(argv[optind++]);
196 if (pidfile_exists(PROGNAME, port))
199 memset(&srvaddr, 0, sizeof(srvaddr));
200 srvaddr.sin_family = AF_INET;
201 srvaddr.sin_port = htons(port);
202 srvaddr.sin_addr.s_addr = INADDR_ANY;
204 fd = socket(PF_INET, SOCK_STREAM, 0);
206 perror("opening socket");
211 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &o, sizeof(o))) {
212 perror("Cannot set REUSEADDR socket opt");
219 rc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &o, sizeof (o));
222 perror ("Cannot disable nagle");
229 rc = setsockopt (fd, SOL_SOCKET, SO_SNDBUF, &txmem, sizeof (txmem));
232 perror ("Cannot set write buffer size");
239 rc = setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &rxmem, sizeof (rxmem));
242 perror ("Cannot set read buffer size");
247 rc = bind(fd, (struct sockaddr *)&srvaddr, sizeof(srvaddr));
253 if (listen(fd, 127)) {
257 fprintf(stderr, "listening on port %d\n", port);
259 pfd = open("/dev/portals", O_RDWR);
261 perror("opening portals device");
265 rc = daemon(1, noclose);
267 perror("daemon(): ");
271 openlog(PROGNAME, LOG_PID, LOG_DAEMON);
272 syslog(LOG_INFO, "started, listening on port %d\n", port);
273 create_pidfile(PROGNAME, port);
276 struct sockaddr_in clntaddr;
277 int len = sizeof(clntaddr);
279 struct portal_ioctl_data data;
280 struct portals_cfg pcfg;
282 cfd = accept(fd, (struct sockaddr *)&clntaddr, &len);
289 show_connection (cfd, clntaddr.sin_addr.s_addr);
291 PCFG_INIT(pcfg, NAL_CMD_REGISTER_PEER_FD);
294 pcfg.pcfg_flags = bind_irq;
295 pcfg.pcfg_misc = SOCKNAL_CONN_NONE; /* == incoming connection */
297 PORTAL_IOC_INIT(data);
298 data.ioc_pbuf1 = (char*)&pcfg;
299 data.ioc_plen1 = sizeof(pcfg);
301 if (ioctl(pfd, IOC_PORTAL_NAL_CMD, &data) < 0) {
302 perror("ioctl failed");
304 printf("client registered\n");
308 perror ("close failed");