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>
17 #include <portals/api-support.h>
18 #include <portals/list.h>
19 #include <portals/lib-types.h>
20 #include <portals/socknal.h>
22 /* should get this from autoconf somehow */
24 #define PIDFILE_DIR "/var/run"
27 #define PROGNAME "acceptor"
29 void create_pidfile(char *name, int port)
34 snprintf(pidfile, sizeof(pidfile), "%s/%s-%d.pid",
35 PIDFILE_DIR, name, port);
37 if ((fp = fopen(pidfile, "w"))) {
38 fprintf(fp, "%d\n", getpid());
41 syslog(LOG_ERR, "%s: %s\n", pidfile,
46 int pidfile_exists(char *name, int port)
50 snprintf(pidfile, sizeof(pidfile), "%s/%s-%d.pid",
51 PIDFILE_DIR, name, port);
53 if (!access(pidfile, F_OK)) {
54 fprintf(stderr, "%s: exists, acceptor already running.\n",
62 parse_size (int *sizep, char *str)
67 switch (sscanf (str, "%d%1[gGmMkK]", &size, mod))
102 show_connection (int fd, __u32 net_ip)
104 struct hostent *h = gethostbyaddr ((char *)&net_ip, sizeof net_ip, AF_INET);
105 __u32 host_ip = ntohl (net_ip);
112 len = sizeof (txmem);
113 if (getsockopt (fd, SOL_SOCKET, SO_SNDBUF, &txmem, &len) != 0)
114 perror ("Cannot get write buffer size");
116 len = sizeof (rxmem);
117 if (getsockopt (fd, SOL_SOCKET, SO_RCVBUF, &rxmem, &len) != 0)
118 perror ("Cannot get read buffer size");
120 len = sizeof (nonagle);
121 if (getsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &nonagle, &len) != 0)
122 perror ("Cannot get nagle");
125 snprintf (host, sizeof(host), "%d.%d.%d.%d", (host_ip >> 24) & 0xff,
126 (host_ip >> 16) & 0xff, (host_ip >> 8) & 0xff, host_ip & 0xff);
128 snprintf (host, sizeof(host), "%s", h->h_name);
130 syslog (LOG_INFO, "Accepted host: %s snd: %d rcv %d nagle: %s\n",
131 host, txmem, rxmem, nonagle ? "disabled" : "enabled");
137 fprintf (stderr, "Usage: %s [-r recv_mem] [-s send_mem] [-n] [-N nal_id] port\n", myname);
141 int main(int argc, char **argv)
143 int o, fd, rc, port, pfd;
144 struct sockaddr_in srvaddr;
153 while ((c = getopt (argc, argv, "N:r:s:nli")) != -1)
157 if (parse_size (&rxmem, optarg) != 0 || rxmem < 0)
162 if (parse_size (&txmem, optarg) != 0 || txmem < 0)
179 if (parse_size(&nal, optarg) != 0 ||
180 nal < 0 || nal > NAL_MAX_NR)
192 port = atol(argv[optind++]);
194 if (pidfile_exists(PROGNAME, port))
197 memset(&srvaddr, 0, sizeof(srvaddr));
198 srvaddr.sin_family = AF_INET;
199 srvaddr.sin_port = htons(port);
200 srvaddr.sin_addr.s_addr = INADDR_ANY;
202 fd = socket(PF_INET, SOCK_STREAM, 0);
204 perror("opening socket");
209 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &o, sizeof(o))) {
210 perror("Cannot set REUSEADDR socket opt");
217 rc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &o, sizeof (o));
220 perror ("Cannot disable nagle");
227 rc = setsockopt (fd, SOL_SOCKET, SO_SNDBUF, &txmem, sizeof (txmem));
230 perror ("Cannot set write buffer size");
237 rc = setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &rxmem, sizeof (rxmem));
240 perror ("Cannot set read buffer size");
245 rc = bind(fd, (struct sockaddr *)&srvaddr, sizeof(srvaddr));
251 if (listen(fd, 127)) {
255 fprintf(stderr, "listening on port %d\n", port);
257 pfd = open("/dev/portals", O_RDWR);
259 perror("opening portals device");
263 rc = daemon(1, noclose);
265 perror("daemon(): ");
269 openlog(PROGNAME, LOG_PID, LOG_DAEMON);
270 syslog(LOG_INFO, "started, listening on port %d\n", port);
271 create_pidfile(PROGNAME, port);
274 struct sockaddr_in clntaddr;
275 int len = sizeof(clntaddr);
277 struct portal_ioctl_data data;
278 struct portals_cfg pcfg;
280 cfd = accept(fd, (struct sockaddr *)&clntaddr, &len);
287 show_connection (cfd, clntaddr.sin_addr.s_addr);
289 PCFG_INIT(pcfg, NAL_CMD_REGISTER_PEER_FD);
292 pcfg.pcfg_flags = bind_irq;
293 pcfg.pcfg_misc = SOCKNAL_CONN_NONE; /* == incoming connection */
295 PORTAL_IOC_INIT(data);
296 data.ioc_pbuf1 = (char*)&pcfg;
297 data.ioc_plen1 = sizeof(pcfg);
299 if (ioctl(pfd, IOC_PORTAL_NAL_CMD, &data) < 0) {
300 perror("ioctl failed");
302 printf("client registered\n");
306 perror ("close failed");