int __init kserver_init(void) { int r; struct socket *lsk; struct sockaddr_in saddr; r = ss_hooks_register(&ssocket_hooks); if (r) { printk(KERN_ERR "Can't register synchronous socket callbacks\n"); return r; } r = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &lsk); if (r) { printk(KERN_ERR "Can't listening socket\n"); goto err_create; } inet_sk(lsk->sk)->freebind = 1; lsk->sk->sk_reuse = 1; /* Set TCP handlers. */ ss_tcp_set_listen(lsk, (SsProto *)&my_proto); memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl(INADDR_ANY); saddr.sin_port = htons(PORT); r = lsk->ops->bind(lsk, (struct sockaddr *)&saddr, sizeof(saddr)); if (r) { printk(KERN_ERR "Can't bind listening socket\n"); goto err_call; } r = lsk->ops->listen(lsk, 1000); if (r) { printk(KERN_ERR "Can't listen on socket\n"); goto err_call; } return 0; err_call: sock_release(lsk); err_create: ss_hooks_unregister(&ssocket_hooks); return r; }
/** * Parse IP address, create a socket and bind it with the address, * but not yet start listening. */ static int add_listen_sock(TfwAddr *addr, int type) { int r; SsProto *proto; struct socket *s; if (listen_socks_n == ARRAY_SIZE(listen_socks)) { TFW_ERR("maximum number of listen sockets (%d) is reached\n", listen_socks_n); return -ENOBUFS; } r = sock_create_kern(addr->sa.sa_family, SOCK_STREAM, IPPROTO_TCP, &s); if (r) { TFW_ERR("can't create socket (err: %d)\n", r); return r; } inet_sk(s->sk)->freebind = 1; s->sk->sk_reuse = 1; r = s->ops->bind(s, &addr->sa, tfw_addr_sa_len(addr)); if (r) { TFW_ERR_ADDR("can't bind to", addr); sock_release(s); return r; } proto = &protos[listen_socks_n]; proto->type = type; BUG_ON(proto->listener); ss_tcp_set_listen(s, proto); TFW_DBG("created front-end socket: sk=%p\n", s->sk); BUG_ON(listen_socks[listen_socks_n]); listen_socks[listen_socks_n] = s; ++listen_socks_n; return 0; }
/** * Create a listening front-end socket. */ static int __open_listen_socket(SsProto *proto, void *addr) { struct socket *s; unsigned short family = *(unsigned short *)addr; unsigned short sza = family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); int r; r = sock_create_kern(family, SOCK_STREAM, IPPROTO_TCP, &s); if (r) { TFW_ERR("Can't create front-end listening socket (%d)\n", r); return r; } inet_sk(s->sk)->freebind = 1; s->sk->sk_reuse = 1; r = s->ops->bind(s, (struct sockaddr *)addr, sza); if (r) { TFW_ERR("Can't bind front-end listening socket (%d)\n", r); goto err; } ss_tcp_set_listen(s, proto); TFW_DBG("Created listening socket %p\n", s->sk); /* TODO adjust /proc/sys/net/core/somaxconn */ r = s->ops->listen(s, 1024); if (r) { TFW_ERR("Can't listen on front-end socket (%d)\n", r); goto err; } return r; err: sock_release(s); return r; }