/* Now we will only be called whenever we need to do * something, but we must be sure to process all of the * sockets that need it. */ void net_timer (unsigned long data) { struct sock *sk = (struct sock*)data; int why = sk->timeout; /* Only process if socket is not in use. */ if (atomic_read(&sk->sock_readers)) { /* Try again later. */ mod_timer(&sk->timer, jiffies+HZ/20); return; } /* Always see if we need to send an ack. */ if (sk->tp_pinfo.af_tcp.delayed_acks && !sk->zapped) { sk->prot->read_wakeup (sk); if (!sk->dead) sk->data_ready(sk,0); } /* Now we need to figure out why the socket was on the timer. */ switch (why) { case TIME_DONE: /* If the socket hasn't been closed off, re-try a bit later. */ if (!sk->dead) { net_reset_timer(sk, TIME_DONE, TCP_DONE_TIME); break; } if (sk->state != TCP_CLOSE) { printk (KERN_DEBUG "non CLOSE socket in time_done\n"); break; } destroy_sock (sk); break; case TIME_DESTROY: /* We've waited for a while for all the memory associated with * the socket to be freed. */ destroy_sock(sk); break; case TIME_CLOSE: /* We've waited long enough, close the socket. */ tcp_set_state(sk, TCP_CLOSE); sk->shutdown = SHUTDOWN_MASK; if (!sk->dead) sk->state_change(sk); net_reset_timer (sk, TIME_DONE, TCP_DONE_TIME); break; default: /* I want to see these... */ printk ("net_timer: timer expired - reason %d is unknown\n", why); break; } }
static void packet_close(struct sock *sk, unsigned long timeout) { /* * Stop more data and kill the socket off. */ lock_sock(sk); sk->state = TCP_CLOSE; /* * Unhook the notifier */ unregister_netdevice_notifier(&sk->protinfo.af_packet.notifier); if(sk->protinfo.af_packet.prot_hook) { /* * Remove the protocol hook */ dev_remove_pack((struct packet_type *)sk->protinfo.af_packet.prot_hook); /* * Dispose of litter carefully. */ kfree_s((void *)sk->protinfo.af_packet.prot_hook, sizeof(struct packet_type)); sk->protinfo.af_packet.prot_hook = NULL; } release_sock(sk); destroy_sock(sk); }
static int ip_proto_accept (struct socket *sock, struct socket *newsock, int flags) { volatile struct sock *sk1, *sk2; sk1= sock->data; if (sk1 == NULL) { printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); return (0); } newsock->data = NULL; if (sk1->prot->accept == NULL) return (-EOPNOTSUPP); /* restore the state if we have been interrupted, and then returned. */ if (sk1->pair != NULL ) { sk2 = sk1->pair; sk1->pair = NULL; } else { sk2 = sk1->prot->accept (sk1,flags); if (sk2 == NULL) return (-sk1->err); } newsock->data = (void *)sk2; sk2->sleep = (void *)newsock->wait; newsock->conn = NULL; if (flags & O_NONBLOCK) return (0); cli(); /* avoid the race. */ while (sk2->state == TCP_SYN_RECV) { interruptible_sleep_on (sk2->sleep); if (current->signal & ~current->blocked) { sti(); sk1->pair = sk2; sk2->sleep = NULL; newsock->data = NULL; return (-ERESTARTSYS); } } sti(); if (sk2->state != TCP_ESTABLISHED && sk2->err) { int err; err = -sk2->err; destroy_sock (sk2); newsock->data = NULL; return (err); } newsock->state = SS_CONNECTED; return (0); }
static void udp_close(struct sock *sk, unsigned long timeout) { lock_sock(sk); sk->state = TCP_CLOSE; sk->dead = 1; release_sock(sk); udp_v4_unhash(sk); destroy_sock(sk); }
static void raw_close(struct sock *sk, unsigned long timeout) { sk->state = TCP_CLOSE; #ifdef CONFIG_IP_MROUTE if(sk==mroute_socket) { mroute_close(sk); mroute_socket=NULL; } #endif destroy_sock(sk); }
static int inet_create(struct socket *sock, int protocol) { struct sock *sk; struct proto *prot; int err; sk = (struct sock *) kmalloc(sizeof(*sk), GFP_KERNEL); if (sk == NULL) return(-ENOBUFS); sk->num = 0; sk->reuse = 0; switch(sock->type) { case SOCK_STREAM: case SOCK_SEQPACKET: if (protocol && protocol != IPPROTO_TCP) { kfree_s((void *)sk, sizeof(*sk)); return(-EPROTONOSUPPORT); } protocol = IPPROTO_TCP; /* TCP_NO_CHECK tcp协议全局默认值 */ sk->no_check = TCP_NO_CHECK; prot = &tcp_prot; break; case SOCK_DGRAM: if (protocol && protocol != IPPROTO_UDP) { kfree_s((void *)sk, sizeof(*sk)); return(-EPROTONOSUPPORT); } protocol = IPPROTO_UDP; sk->no_check = UDP_NO_CHECK; prot=&udp_prot; break; case SOCK_RAW: if (!suser()) { kfree_s((void *)sk, sizeof(*sk)); return(-EPERM); } if (!protocol) { kfree_s((void *)sk, sizeof(*sk)); return(-EPROTONOSUPPORT); } prot = &raw_prot; sk->reuse = 1; sk->no_check = 0; /* * Doesn't matter no checksum is * performed anyway. */ sk->num = protocol; break; case SOCK_PACKET: if (!suser()) { kfree_s((void *)sk, sizeof(*sk)); return(-EPERM); } if (!protocol) { kfree_s((void *)sk, sizeof(*sk)); return(-EPROTONOSUPPORT); } prot = &packet_prot; sk->reuse = 1; sk->no_check = 0; /* Doesn't matter no checksum is * performed anyway. */ sk->num = protocol; break; default: kfree_s((void *)sk, sizeof(*sk)); return(-ESOCKTNOSUPPORT); } sk->socket = sock; #ifdef CONFIG_TCP_NAGLE_OFF sk->nonagle = 1; #else sk->nonagle = 0; #endif sk->type = sock->type; sk->stamp.tv_sec=0; sk->protocol = protocol; // 传输层协议值 sk->wmem_alloc = 0; sk->rmem_alloc = 0; sk->sndbuf = SK_WMEM_MAX; // 初始化该链接的最大写缓冲区 sk->rcvbuf = SK_RMEM_MAX; // 初始化该链接的最大读缓冲区 sk->pair = NULL; sk->opt = NULL; sk->write_seq = 0; sk->acked_seq = 0; sk->copied_seq = 0; sk->fin_seq = 0; sk->urg_seq = 0; sk->urg_data = 0; sk->proc = 0; sk->rtt = 0; /*TCP_WRITE_TIME << 3;*/ sk->rto = TCP_TIMEOUT_INIT; /*TCP_WRITE_TIME*/ sk->mdev = 0; sk->backoff = 0; sk->packets_out = 0; sk->cong_window = 1; /* start with only sending one packet at a time. * 拥塞窗口设置为1,即tcp首先进入慢启动状态 */ sk->cong_count = 0; sk->ssthresh = 0; sk->max_window = 0; sk->urginline = 0; sk->intr = 0; sk->linger = 0; sk->destroy = 0; sk->priority = 1; sk->shutdown = 0; sk->keepopen = 0; sk->zapped = 0; sk->done = 0; sk->ack_backlog = 0; sk->window = 0; sk->bytes_rcv = 0; sk->state = TCP_CLOSE; // 本地初创socket,状态是关闭状态 sk->dead = 0; sk->ack_timed = 0; sk->partial = NULL; sk->user_mss = 0; sk->debug = 0; /* 最大可暂缓应答的数据字节数 */ /* this is how many unacked bytes we will accept for this socket. */ sk->max_unacked = 2048; /* needs to be at most 2 full packets. */ /* 已发送但未收到确认的数据报个数上限 */ /* how many packets we should send before forcing an ack. if this is set to zero it is the same as sk->delay_acks = 0 */ sk->max_ack_backlog = 0; sk->inuse = 0; sk->delay_acks = 0; skb_queue_head_init(&sk->write_queue); skb_queue_head_init(&sk->receive_queue); sk->mtu = 576; // mtu设置成保守的576,该大小在绝大多数连接上不会造成碎片 sk->prot = prot; sk->sleep = sock->wait; sk->daddr = 0; sk->saddr = 0 /* ip_my_addr() */; sk->err = 0; sk->next = NULL; sk->pair = NULL; sk->send_tail = NULL; sk->send_head = NULL; sk->timeout = 0; sk->broadcast = 0; sk->localroute = 0; init_timer(&sk->timer); init_timer(&sk->retransmit_timer); sk->timer.data = (unsigned long)sk; sk->timer.function = &net_timer; skb_queue_head_init(&sk->back_log); sk->blog = 0; sock->data =(void *) sk; sk->dummy_th.doff = sizeof(sk->dummy_th)/4; sk->dummy_th.res1=0; sk->dummy_th.res2=0; sk->dummy_th.urg_ptr = 0; sk->dummy_th.fin = 0; sk->dummy_th.syn = 0; sk->dummy_th.rst = 0; sk->dummy_th.psh = 0; sk->dummy_th.ack = 0; sk->dummy_th.urg = 0; sk->dummy_th.dest = 0; sk->ip_tos=0; sk->ip_ttl=64; #ifdef CONFIG_IP_MULTICAST sk->ip_mc_loop=1; sk->ip_mc_ttl=1; *sk->ip_mc_name=0; sk->ip_mc_list=NULL; #endif sk->state_change = def_callback1; sk->data_ready = def_callback2; sk->write_space = def_callback3; sk->error_report = def_callback1; if (sk->num) { /* * It assumes that any protocol which allows * the user to assign a number at socket * creation time automatically * shares. */ put_sock(sk->num, sk); sk->dummy_th.source = ntohs(sk->num); } if (sk->prot->init) { err = sk->prot->init(sk); if (err != 0) { destroy_sock(sk); return(err); } } return(0); }
static int inet_accept(struct socket *sock, struct socket *newsock, int flags) { struct sock *sk1, *sk2; int err; /* sk1指向监听套接字的sk结构 */ sk1 = (struct sock *) sock->data; /* * We've been passed an extra socket. * We need to free it up because the tcp module creates * its own when it accepts one. */ if (newsock->data) { struct sock *sk=(struct sock *)newsock->data; newsock->data=NULL; sk->dead = 1; destroy_sock(sk); } if (sk1->prot->accept == NULL) return(-EOPNOTSUPP); /* Restore the state if we have been interrupted, and then returned. */ /* sk->pair中存放上次被信号打断的accpet过程中取出的连接请求 */ if (sk1->pair != NULL ) { sk2 = sk1->pair; sk1->pair = NULL; } else { sk2 = sk1->prot->accept(sk1,flags); if (sk2 == NULL) { if (sk1->err <= 0) printk("Warning sock.c:sk1->err <= 0. Returning non-error.\n"); err=sk1->err; sk1->err=0; return(-err); } } // 执行到这里:已经从请求队列中取出一个请求 newsock->data = (void *)sk2; sk2->sleep = newsock->wait; sk2->socket = newsock; newsock->conn = NULL; // INET域中,该字段为NULL if (flags & O_NONBLOCK) // 非阻塞accpet可能会返回尚未established的连接 return(0); // 区别与尾端返回的不同,在尾端返回处设置newsock->state = SS_CONNECTED cli(); /* avoid the race. */ while(sk2->state == TCP_SYN_RECV) // 等待连接完成 { interruptible_sleep_on(sk2->sleep); if (current->signal & ~current->blocked) { sti(); sk1->pair = sk2; // 如果被信号打断,就把已经取出来的连接请求放入sk->pair中暂存 sk2->sleep = NULL; sk2->socket=NULL; newsock->data = NULL; return(-ERESTARTSYS); } } sti(); if (sk2->state != TCP_ESTABLISHED && sk2->err > 0) // 接收过程出错 { err = -sk2->err; sk2->err=0; sk2->dead=1; /* ANK */ destroy_sock(sk2); newsock->data = NULL; return(err); } newsock->state = SS_CONNECTED; return(0); }
static int inet6_create(struct socket *sock, int protocol) { struct sock *sk; struct proto *prot; sk = sk_alloc(PF_INET6, GFP_KERNEL, 1); if (sk == NULL) goto do_oom; if(sock->type == SOCK_STREAM || sock->type == SOCK_SEQPACKET) { if (protocol && protocol != IPPROTO_TCP) goto free_and_noproto; protocol = IPPROTO_TCP; prot = &tcpv6_prot; sock->ops = &inet6_stream_ops; } else if(sock->type == SOCK_DGRAM) { if (protocol && protocol != IPPROTO_UDP) goto free_and_noproto; protocol = IPPROTO_UDP; sk->no_check = UDP_NO_CHECK; prot=&udpv6_prot; sock->ops = &inet6_dgram_ops; } else if(sock->type == SOCK_RAW) { if (!capable(CAP_NET_RAW)) goto free_and_badperm; if (!protocol) goto free_and_noproto; prot = &rawv6_prot; sock->ops = &inet6_dgram_ops; sk->reuse = 1; sk->num = protocol; } else { goto free_and_badtype; } sock_init_data(sock, sk); sk->destruct = NULL; sk->zapped = 0; sk->family = PF_INET6; sk->protocol = protocol; sk->prot = prot; sk->backlog_rcv = prot->backlog_rcv; sk->timer.data = (unsigned long)sk; sk->timer.function = &net_timer; sk->net_pinfo.af_inet6.hop_limit = -1; sk->net_pinfo.af_inet6.mcast_hops = -1; sk->net_pinfo.af_inet6.mc_loop = 1; sk->net_pinfo.af_inet6.pmtudisc = IPV6_PMTUDISC_WANT; /* Init the ipv4 part of the socket since we can have sockets * using v6 API for ipv4. */ sk->ip_ttl = 64; sk->ip_mc_loop = 1; sk->ip_mc_ttl = 1; sk->ip_mc_index = 0; sk->ip_mc_list = NULL; if (sk->type==SOCK_RAW && protocol==IPPROTO_RAW) sk->ip_hdrincl=1; if (sk->num) { /* It assumes that any protocol which allows * the user to assign a number at socket * creation time automatically shares. */ sk->sport = ntohs(sk->num); sk->prot->hash(sk); add_to_prot_sklist(sk); } if (sk->prot->init) { int err = sk->prot->init(sk); if (err != 0) { destroy_sock(sk); return(err); } } MOD_INC_USE_COUNT; return(0); free_and_badtype: sk_free(sk); return -ESOCKTNOSUPPORT; free_and_badperm: sk_free(sk); return -EPERM; free_and_noproto: sk_free(sk); return -EPROTONOSUPPORT; do_oom: return -ENOBUFS; }
static int ip_proto_create (struct socket *sock, int protocol) { volatile struct sock *sk; struct proto *prot; int err; sk = malloc (sizeof (*sk)); if (sk == NULL) return (-ENOMEM); sk->num = 0; switch (sock->type) { case SOCK_STREAM: case SOCK_SEQPACKET: if (protocol && protocol != IP_TCP) { free_s ((void *)sk, sizeof (*sk)); return (-EPROTONOSUPPORT); } sk->no_check = TCP_NO_CHECK; prot = &tcp_prot; break; case SOCK_DGRAM: if (protocol && protocol != IP_UDP) { free_s ((void *)sk, sizeof (*sk)); return (-EPROTONOSUPPORT); } sk->no_check = UDP_NO_CHECK; prot=&udp_prot; break; case SOCK_RAW: if (!suser()) { free_s ((void *)sk, sizeof (*sk)); return (-EPERM); } if (!protocol) { free_s ((void *)sk, sizeof (*sk)); return (-EPROTONOSUPPORT); } prot = &raw_prot; sk->reuse = 1; sk->no_check = 0; /* doesn't matter no checksum is preformed anyway. */ sk->num = protocol; break; case SOCK_PACKET: if (!suser()) { free_s ((void *)sk, sizeof (*sk)); return (-EPERM); } if (!protocol) { free_s ((void *)sk, sizeof (*sk)); return (-EPROTONOSUPPORT); } prot = &packet_prot; sk->reuse = 1; sk->no_check = 0; /* doesn't matter no checksum is preformed anyway. */ sk->num = protocol; break; default: free_s ((void *)sk, sizeof (*sk)); return (-ESOCKTNOSUPPORT); } sk->protocol = protocol; sk->wmem_alloc = 0; sk->rmem_alloc = 0; sk->pair = NULL; sk->opt = NULL; sk->send_seq = 0; sk->acked_seq = 0; sk->copied_seq = 0; sk->fin_seq = 0; sk->proc = 0; sk->rtt = TCP_WRITE_TIME; sk->packets_out = 0; sk->cong_window = 1; /* start with only sending one packet at a time. */ sk->exp_growth = 1; /* if set cong_window grow exponentially every time we get an ack. */ sk->urginline = 0; sk->intr = 0; sk->linger = 0; sk->destroy = 0; sk->reuse = 0; sk->priority = 1; sk->shutdown = 0; sk->urg = 0; sk->keepopen = 0; sk->done = 0; sk->ack_backlog = 0; sk->window = 0; sk->bytes_rcv = 0; sk->state = TCP_CLOSE; sk->dead = 0; sk->ack_timed = 0; /* this is how many unacked bytes we will accept for this socket. */ sk->max_unacked = 2048; /* needs to be at most 2 full packets. */ /* how many packets we should send before forcing an ack. if this is set to zero it is the same as sk->delay_acks = 0 */ sk->max_ack_backlog = MAX_ACK_BACKLOG; sk->inuse = 0; sk->delay_acks = 1; /* default to waiting a while before sending acks. */ sk->wback = NULL; sk->wfront = NULL; sk->rqueue = NULL; sk->mtu = 576; sk->prot = prot; sk->sleep = sock->wait; sk->daddr = 0; sk->saddr = MY_IP_ADDR; sk->err = 0; sk->next = NULL; sk->pair = NULL; sk->send_tail = NULL; sk->send_head = NULL; sk->time_wait.len = TCP_CONNECT_TIME; sk->time_wait.when = 0; sk->time_wait.sk = sk; sk->time_wait.next = NULL; sk->timeout = 0; sk->back_log = NULL; sk->blog = 0; sock->data =(void *) sk; sk->dummy_th.doff = sizeof (sk->dummy_th)/4; sk->dummy_th.res1=0; sk->dummy_th.res2=0; sk->dummy_th.urg_ptr = 0; sk->dummy_th.fin = 0; sk->dummy_th.syn = 0; sk->dummy_th.rst = 0; sk->dummy_th.psh = 0; sk->dummy_th.ack = 0; sk->dummy_th.urg = 0; sk->dummy_th.dest = 0; if (sk->num) { put_sock (sk->num, sk); } else { sk->num = get_new_socknum(sk->prot, 0); } /* make sure there was a free socket. */ if (sk->num == 0) { destroy_sock(sk); return (-EAGAIN); } put_sock(sk->num, sk); sk->dummy_th.source = net16(sk->num); if (sk->prot->init) { err = sk->prot->init(sk); if (err != 0) { destroy_sock (sk); return (err); } } return (0); }
/* 每个struct sock的时钟函数 */ void net_timer (unsigned long data) { struct sock *sk = (struct sock*)data; /* 相当于获取时钟的类型吧, */ int why = sk->timeout; /* timeout is overwritten by 'delete_timer' and 'reset_timer' */ /* 判断sock是否已被其他进程使用,或者当前是否正在执行网络的下半部分, * 如果当前正在执行网络的下半部分,则重新设置sock的timer,同时添加到 * 内核时钟当中,等待下次执行 */ if (sk->inuse || in_inet_bh()) { sk->timer.expires = 10; add_timer(&sk->timer); return; } /* 设置sock为用 */ sk->inuse = 1; DPRINTF ((DBG_TMR, "net_timer: found sk=%X why = %d\n", sk, why)); if (sk->wfront && before(sk->window_seq, sk->wfront->h.seq) && sk->send_head == NULL && sk->ack_backlog == 0 && sk->state != TCP_TIME_WAIT) reset_timer(sk, TIME_PROBE0, sk->rto); else if (sk->keepopen) reset_timer (sk, TIME_KEEPOPEN, TCP_TIMEOUT_LEN); /* Always see if we need to send an ack. */ /* 看看还有没有收到的数据包没有应答 */ if (sk->ack_backlog) { /* sock发送确认数据包*/ sk->prot->read_wakeup (sk); if (! sk->dead) wake_up_interruptible (sk->sleep); } /* Now we need to figure out why the socket was on the timer. */ switch (why) { case TIME_DONE: if (! sk->dead || sk->state != TCP_CLOSE) { printk ("non dead socket in time_done\n"); release_sock (sk); break; } destroy_sock (sk); break; case TIME_DESTROY: /* We've waited for a while for all the memory associated with * the socket to be freed. We need to print an error message. */ /* 如果sock的发送缓冲区和接收缓冲区都为空,则直接在后面的语句当中释放 */ if(sk->wmem_alloc!=0 || sk->rmem_alloc!=0) { DPRINTF ((DBG_TMR, "possible memory leak. sk = %X\n", sk)); sk->wmem_alloc++; /* So it DOESNT go away */ destroy_sock (sk); sk->wmem_alloc--; /* Might now have hit 0 - fall through and do it again if so */ sk->inuse = 0; /* This will be ok, the destroy won't totally work */ } if(sk->wmem_alloc==0 && sk->rmem_alloc==0) destroy_sock(sk); /* Socket gone, DONT update sk->inuse! */ break; case TIME_CLOSE: /* We've waited long enough, close the socket. */ sk->state = TCP_CLOSE; delete_timer (sk); /* Kill the ARP entry in case the hardware has changed. */ arp_destroy_maybe (sk->daddr); if (!sk->dead) wake_up_interruptible (sk->sleep); sk->shutdown = SHUTDOWN_MASK; reset_timer (sk, TIME_DESTROY, TCP_DONE_TIME); release_sock (sk); break; case TIME_PROBE0: /* 窗口探测定时器,也被称为坚持定时器 */ tcp_send_probe0(sk); release_sock (sk); break; case TIME_WRITE: /* 超时重传定时器 */ /* try to retransmit. */ /* It could be we got here because we needed to send an ack. * So we need to check for that. */ if (sk->send_head) { if (jiffies < (sk->send_head->when + sk->rto)) { reset_timer (sk, TIME_WRITE, (sk->send_head->when + sk->rto - jiffies)); release_sock (sk); break; } /* printk("timer: seq %d retrans %d out %d cong %d\n", sk->send_head->h.seq, sk->retransmits, sk->packets_out, sk->cong_window); */ DPRINTF ((DBG_TMR, "retransmitting.\n")); /* 调用tcp协议的超时重传函数 */ sk->prot->retransmit (sk, 0); if ((sk->state == TCP_ESTABLISHED && sk->retransmits && !(sk->retransmits & 7)) || (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR1)) { DPRINTF ((DBG_TMR, "timer.c TIME_WRITE time-out 1\n")); arp_destroy_maybe (sk->daddr); ip_route_check (sk->daddr); } if (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR2) { DPRINTF ((DBG_TMR, "timer.c TIME_WRITE time-out 2\n")); sk->err = ETIMEDOUT; if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2 || sk->state == TCP_LAST_ACK) { sk->state = TCP_TIME_WAIT; reset_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN); } else { sk->prot->close (sk, 1); break; } } } release_sock (sk); break; case TIME_KEEPOPEN: /* 保活定时器 */ /* Send something to keep the connection open. */ if (sk->prot->write_wakeup) sk->prot->write_wakeup (sk); sk->retransmits++; /* 因为是重发定时,所以会增加超时重发次数 */ if (sk->shutdown == SHUTDOWN_MASK) { sk->prot->close (sk, 1); sk->state = TCP_CLOSE; } if ((sk->state == TCP_ESTABLISHED && sk->retransmits && !(sk->retransmits & 7)) || (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR1)) { DPRINTF ((DBG_TMR, "timer.c TIME_KEEPOPEN time-out 1\n")); arp_destroy_maybe (sk->daddr); ip_route_check (sk->daddr); release_sock (sk); break; } if (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR2) { DPRINTF ((DBG_TMR, "timer.c TIME_KEEPOPEN time-out 2\n")); arp_destroy_maybe (sk->daddr); sk->err = ETIMEDOUT; if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2) { sk->state = TCP_TIME_WAIT; if (!sk->dead) wake_up_interruptible (sk->sleep); release_sock (sk); } else { sk->prot->close (sk, 1); } break; } release_sock (sk); break; default: printk ("net timer expired - reason unknown, sk=%08X\n", (int)sk); release_sock (sk); break; } }
void net_timer (unsigned long data) { struct sock *sk = (struct sock*)data; int why = sk->timeout; /* * only process if socket is not in use */ if (sk->users) { sk->timer.expires = jiffies+HZ; add_timer(&sk->timer); sti(); return; } /* Always see if we need to send an ack. */ if (sk->ack_backlog && !sk->zapped) { sk->prot->read_wakeup (sk); if (! sk->dead) sk->data_ready(sk,0); } /* Now we need to figure out why the socket was on the timer. */ switch (why) { case TIME_DONE: /* If the socket hasn't been closed off, re-try a bit later */ if (!sk->dead) { reset_timer(sk, TIME_DONE, TCP_DONE_TIME); break; } if (sk->state != TCP_CLOSE) { printk ("non CLOSE socket in time_done\n"); break; } destroy_sock (sk); break; case TIME_DESTROY: /* * We've waited for a while for all the memory associated with * the socket to be freed. */ destroy_sock(sk); break; case TIME_CLOSE: /* We've waited long enough, close the socket. */ sk->state = TCP_CLOSE; delete_timer (sk); if (!sk->dead) sk->state_change(sk); sk->shutdown = SHUTDOWN_MASK; reset_timer (sk, TIME_DONE, TCP_DONE_TIME); break; default: printk ("net_timer: timer expired - reason %d is unknown\n", why); break; } }
static int inet_accept(struct socket *sock, struct socket *newsock, int flags) { struct sock *sk1, *sk2; int err; sk1 = (struct sock *) sock->data; /* * We've been passed an extra socket. * We need to free it up because the tcp module creates * its own when it accepts one. */ if (newsock->data) { struct sock *sk=(struct sock *)newsock->data; newsock->data=NULL; sk->dead = 1; destroy_sock(sk); } if (sk1->prot->accept == NULL) return(-EOPNOTSUPP); /* Restore the state if we have been interrupted, and then returned. */ if (sk1->pair != NULL ) { sk2 = sk1->pair; sk1->pair = NULL; } else { sk2 = sk1->prot->accept(sk1,flags); if (sk2 == NULL) { if (sk1->err <= 0) printk("Warning sock.c:sk1->err <= 0. Returning non-error.\n"); err=sk1->err; sk1->err=0; return(-err); } } newsock->data = (void *)sk2; sk2->sleep = newsock->wait; sk2->socket = newsock; newsock->conn = NULL; if (flags & O_NONBLOCK) return(0); cli(); /* avoid the race. */ while(sk2->state == TCP_SYN_RECV) { interruptible_sleep_on(sk2->sleep); if (current->signal & ~current->blocked) { sti(); sk1->pair = sk2; sk2->sleep = NULL; sk2->socket=NULL; newsock->data = NULL; return(-ERESTARTSYS); } } sti(); if (sk2->state != TCP_ESTABLISHED && sk2->err > 0) { err = -sk2->err; sk2->err=0; sk2->dead=1; /* ANK */ destroy_sock(sk2); newsock->data = NULL; return(err); } newsock->state = SS_CONNECTED; return(0); }