bool socketer::canAccept() { if(!isClose() && socket_can_read(m_sockfd)) { return true; } return false; }
bool listener_can_accept(struct listener *self) { assert(self != NULL); assert(!self->isfree); if (!self) return false; if (self->sockfd != NET_INVALID_SOCKET) { if (socket_can_read(self->sockfd) > 0) return true; } return false; }
/* * accept new connect. * bigbuf --- accept after, create bigbuf or smallbuf. */ struct socketer *listener_accept(struct listener *self, bool bigbuf) { int e; assert(self != NULL); assert(!self->isfree); if (!self) return NULL; if (self->sockfd == NET_INVALID_SOCKET) return NULL; e = socket_can_read(self->sockfd); /* can accept new connect. */ if (1 == e) { struct sockaddr_storage client_addr; /* connect address info. */ net_sock_len size = sizeof(client_addr); struct socketer *temp; net_socket new_sock = accept(self->sockfd, (struct sockaddr *)&client_addr, &size); if (new_sock == NET_INVALID_SOCKET) return NULL; temp = socketer_create_for_accept(bigbuf, (void *)&new_sock); if (!temp) { socket_close(&new_sock); return NULL; } return temp; } #ifndef NDEBUG else { if (e == -1) { /* select function error. */ debuglog("select socket error!\n"); return NULL; } else if (e == 0) { /* over time. */ debuglog("select socket overtime...error:%ld\n", GetLastError()); return NULL; } } debuglog("end so return null...\n"); #endif return NULL; }
socketer *socketer::accept() { int e; if(isClose()) return NULL; e = socket_can_read(m_sockfd); if( 1 == e ) { struct sockaddr_in client_addr; socketer *temp; net_socket new_sock = accept(m_sockfd, (struct sockaddr *)&client_addr, *size); if(new_sock == NET_INVALID_SOCKET) return NULL; temp = new socketer; if(!temp) { socket_close(&new_sock); return NULL; } return temp; } else { if(e == -1) { debuglog("select socket error!\n"); return NULL; } else if(e == 0) { debuglog("select socket overtime...error:%ld\n",GetLastError()); } } debuglog("end so return null...\n"); return NULL; }
/* * recvfrom() a UDP socket */ void sorecvfrom(struct socket *so) { SockAddress addr; DEBUG_CALL("sorecvfrom"); DEBUG_ARG("so = %lx", (long)so); if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */ char buff[256]; int len; len = socket_recvfrom(so->s, buff, 256, &addr); /* XXX Check if reply is "correct"? */ if(len == -1 || len == 0) { u_char code=ICMP_UNREACH_PORT; if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET; DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n", errno,errno_str)); icmp_error(so->so_m, ICMP_UNREACH,code, 0,errno_str); } else { icmp_reflect(so->so_m); so->so_m = 0; /* Don't mbuf_free() it again! */ } /* No need for this socket anymore, udp_detach it */ udp_detach(so); } else { /* A "normal" UDP packet */ struct mbuf *m; int len; int n; if (!(m = m_get())) return; m->m_data += IF_MAXLINKHDR; /* * XXX Shouldn't FIONREAD packets destined for port 53, * but I don't know the max packet size for DNS lookups */ len = M_FREEROOM(m); /* if (so->so_fport != htons(53)) { */ n = socket_can_read(so->s); if (n > len) { n = (m->m_data - m->m_dat) + m->m_len + n + 1; m_inc(m, n); len = M_FREEROOM(m); } /* } */ m->m_len = socket_recvfrom(so->s, m->m_data, len, &addr); DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n", m->m_len, errno,errno_str)); if(m->m_len<0) { u_char code=ICMP_UNREACH_PORT; if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET; DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code)); icmp_error(so->so_m, ICMP_UNREACH,code, 0,errno_str); m_free(m); } else { /* * Hack: domain name lookup will be used the most for UDP, * and since they'll only be used once there's no need * for the 4 minute (or whatever) timeout... So we time them * out much quicker (10 seconds for now...) */ if (so->so_expire) { if (so->so_faddr_port == 53) so->so_expire = curtime + SO_EXPIREFAST; else so->so_expire = curtime + SO_EXPIRE; } /* if (m->m_len == len) { * m_inc(m, MINCSIZE); * m->m_len = 0; * } */ /* * If this packet was destined for CTL_ADDR, * make it look like that's where it came from, done by udp_output */ udp_output_(so, m, &addr); } /* rx error */ } /* if ping packet */ }