Messages in this thread | | | Date | Mon, 20 Mar 2000 00:46:06 +0300 | From | "Roman V. Shaposhnick" <> | Subject | TCP 'data_ready' callback is broken ? |
| |
Hi,
while developing kernel module that should use sock callback 'data_ready' I have found that for the TCP socket it is never called.
I am totally confused at this point and would appreciate any help or hints or whatever. Please note, that if I try to use this callback for UDP socket everything is perfect ( like it is in RPC subsystem ).
I attach sample module that can be used to reproduce the problem:
yellow# gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/include -c mod.c yellow# cat >> /etc/inetd.conf 565 stream tcp nowait root /usr/bin/yes yes ^D yellow# insmod ./mod.o yellow# netstat -av ...................... tcp 32686 0 localhost:1025 localhost:565 ESTABLISHED tcp 0 62824 localhost:565 localhost:1025 ESTABLISHED ....................... yellow# tail /var/log/messages
Mar 20 00:35:56 yellow kernel: write_space callback Mar 20 00:35:56 yellow kernel: write_space callback Mar 20 00:35:56 yellow kernel: state_change callback Mar 20 00:35:56 yellow kernel: write_space callback Mar 20 00:35:56 yellow last message repeated 14 times Mar 20 00:35:56 yellow kernel: Receiving message y 1 bytes long Mar 20 00:35:56 yellow kernel: Receiving message Mar 20 00:35:56 yellow kernel: 1 bytes long Mar 20 00:35:56 yellow kernel: Receiving message y 1 bytes long Mar 20 00:35:56 yellow kernel: Receiving message Mar 20 00:35:56 yellow kernel: 1 bytes long Mar 20 00:35:56 yellow kernel: Receiving message y 1 bytes long Mar 20 00:35:56 yellow kernel: Receiving message Mar 20 00:35:56 yellow kernel: 1 bytes long Mar 20 00:35:56 yellow kernel: Receiving message y 1 bytes long Mar 20 00:35:56 yellow kernel: Receiving message Mar 20 00:35:56 yellow kernel: 1 bytes long Mar 20 00:35:56 yellow kernel: Receiving message y 1 bytes long Mar 20 00:35:56 yellow kernel: Receiving message Mar 20 00:35:56 yellow kernel: 1 bytes long Mar 20 00:35:56 yellow kernel: write_space callback
As you can see 'data_ready' is never called.
Thanks, Roman. #include <linux/config.h> #include <linux/module.h>
#include <linux/sched.h> #include <linux/kernel.h> #include <linux/mm.h> #include <linux/string.h> #include <linux/stat.h> #include <linux/errno.h> #include <linux/locks.h> #include <linux/unistd.h> #include <linux/file.h> #include <linux/slab.h> #include <linux/lockd/bind.h>
#include <linux/socket.h> #include <linux/in.h> #include <linux/net.h> #include <linux/udp.h> #include <net/sock.h> #include <net/checksum.h> #include <net/udp.h>
#include <asm/system.h> #include <asm/uaccess.h>
static void mod_data_ready(struct sock *sk, int len) { printk("data_ready callback\n"); }
static void mod_state_change(struct sock *sk) { printk("state_change callback\n"); }
static void mod_write_space(struct sock *sk) { printk("write_space callback\n"); }
static struct socket *sock;
static inline int mod_rcv_msg() { unsigned char buf[4]; struct msghdr msg; mm_segment_t oldfs; int result; struct iovec iov;
iov.iov_base = &buf[0]; iov.iov_len = 1;
msg.msg_flags = MSG_DONTWAIT; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_control = NULL; msg.msg_controllen = 0;
oldfs = get_fs(); set_fs(get_ds()); result = sock_recvmsg(sock, &msg, 1, MSG_DONTWAIT); set_fs(oldfs);
printk("Receiving message %c %d bytes long\n", buf[0], result); return result; }
int init_module(void) { struct sockaddr_in sap; int err; int i;
sap.sin_family = AF_INET; sap.sin_port = 13570; sap.sin_addr.s_addr = 16777343;
if ((err = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) { printk("can't create socket (%d).\n", -err); return -1; }
sock->sk->data_ready = mod_data_ready; sock->sk->state_change = mod_state_change; sock->sk->write_space = mod_write_space; err = sock->ops->connect(sock, (struct sockaddr *) &sap, sizeof(struct sockaddr_in), 0);
if (err < 0) { sock_release(sock); printk("TCP connect failed (%d).\n", -err); return -1; }
for (i=0;i<10;i++) mod_rcv_msg();
return 0; }
void cleanup_module(void) { sock_release(sock); }
| |