📄 sockets.c
字号:
break;#endif /* LWIP_IGMP */ default: LWIP_ASSERT("unhandled optname", 0); break; } /* switch (optname) */ break;#if LWIP_TCP/* Level: IPPROTO_TCP */ case IPPROTO_TCP: switch (optname) { case TCP_NODELAY: *(int*)optval = tcp_nagle_disabled(sock->conn->pcb.tcp); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", s, (*(int*)optval)?"on":"off") ); break; case TCP_KEEPALIVE: *(int*)optval = (int)sock->conn->pcb.tcp->keep_idle; LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPALIVE) = %d\n", s, *(int *)optval)); break;#if LWIP_TCP_KEEPALIVE case TCP_KEEPIDLE: *(int*)optval = (int)(sock->conn->pcb.tcp->keep_idle/1000); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPIDLE) = %d\n", s, *(int *)optval)); break; case TCP_KEEPINTVL: *(int*)optval = (int)(sock->conn->pcb.tcp->keep_intvl/1000); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPINTVL) = %d\n", s, *(int *)optval)); break; case TCP_KEEPCNT: *(int*)optval = (int)sock->conn->pcb.tcp->keep_cnt; LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPCNT) = %d\n", s, *(int *)optval)); break;#endif /* LWIP_TCP_KEEPALIVE */ default: LWIP_ASSERT("unhandled optname", 0); break; } /* switch (optname) */ break;#endif /* LWIP_TCP */#if LWIP_UDP && LWIP_UDPLITE /* Level: IPPROTO_UDPLITE */ case IPPROTO_UDPLITE: switch (optname) { case UDPLITE_SEND_CSCOV: *(int*)optval = sock->conn->pcb.udp->chksum_len_tx; LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) = %d\n", s, (*(int*)optval)) ); break; case UDPLITE_RECV_CSCOV: *(int*)optval = sock->conn->pcb.udp->chksum_len_rx; LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) = %d\n", s, (*(int*)optval)) ); break; default: LWIP_ASSERT("unhandled optname", 0); break; } /* switch (optname) */ break;#endif /* LWIP_UDP */ default: LWIP_ASSERT("unhandled level", 0); break; } /* switch (level) */ sys_sem_signal(&sock->conn->op_completed);}intlwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen){ struct lwip_sock *sock = get_socket(s); err_t err = ERR_OK; struct lwip_setgetsockopt_data data; if (!sock) { return -1; } if (NULL == optval) { sock_set_errno(sock, EFAULT); return -1; } /* Do length and type checks for the various options first, to keep it readable. */ switch (level) {/* Level: SOL_SOCKET */ case SOL_SOCKET: switch (optname) { case SO_BROADCAST: /* UNIMPL case SO_DEBUG: */ /* UNIMPL case SO_DONTROUTE: */ case SO_KEEPALIVE: /* UNIMPL case case SO_CONTIMEO: */ /* UNIMPL case case SO_SNDTIMEO: */#if LWIP_SO_RCVTIMEO case SO_RCVTIMEO:#endif /* LWIP_SO_RCVTIMEO */#if LWIP_SO_RCVBUF case SO_RCVBUF:#endif /* LWIP_SO_RCVBUF */ /* UNIMPL case SO_OOBINLINE: */ /* UNIMPL case SO_SNDBUF: */ /* UNIMPL case SO_RCVLOWAT: */ /* UNIMPL case SO_SNDLOWAT: */#if SO_REUSE case SO_REUSEADDR: case SO_REUSEPORT:#endif /* SO_REUSE */ /* UNIMPL case SO_USELOOPBACK: */ if (optlen < sizeof(int)) { err = EINVAL; } break; case SO_NO_CHECK: if (optlen < sizeof(int)) { err = EINVAL; }#if LWIP_UDP if ((sock->conn->type != NETCONN_UDP) || ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) { /* this flag is only available for UDP, not for UDP lite */ err = EAFNOSUPPORT; }#endif /* LWIP_UDP */ break; default: LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname)); err = ENOPROTOOPT; } /* switch (optname) */ break;/* Level: IPPROTO_IP */ case IPPROTO_IP: switch (optname) { /* UNIMPL case IP_HDRINCL: */ /* UNIMPL case IP_RCVDSTADDR: */ /* UNIMPL case IP_RCVIF: */ case IP_TTL: case IP_TOS: if (optlen < sizeof(int)) { err = EINVAL; } break;#if LWIP_IGMP case IP_MULTICAST_TTL: if (optlen < sizeof(u8_t)) { err = EINVAL; } if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { err = EAFNOSUPPORT; } break; case IP_MULTICAST_IF: if (optlen < sizeof(struct in_addr)) { err = EINVAL; } if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { err = EAFNOSUPPORT; } break; case IP_MULTICAST_LOOP: if (optlen < sizeof(u8_t)) { err = EINVAL; } if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { err = EAFNOSUPPORT; } break; case IP_ADD_MEMBERSHIP: case IP_DROP_MEMBERSHIP: if (optlen < sizeof(struct ip_mreq)) { err = EINVAL; } if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { err = EAFNOSUPPORT; } break;#endif /* LWIP_IGMP */ default: LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", s, optname)); err = ENOPROTOOPT; } /* switch (optname) */ break;#if LWIP_TCP/* Level: IPPROTO_TCP */ case IPPROTO_TCP: if (optlen < sizeof(int)) { err = EINVAL; break; } /* If this is no TCP socket, ignore any options. */ if (sock->conn->type != NETCONN_TCP) return 0; switch (optname) { case TCP_NODELAY: case TCP_KEEPALIVE:#if LWIP_TCP_KEEPALIVE case TCP_KEEPIDLE: case TCP_KEEPINTVL: case TCP_KEEPCNT:#endif /* LWIP_TCP_KEEPALIVE */ break; default: LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", s, optname)); err = ENOPROTOOPT; } /* switch (optname) */ break;#endif /* LWIP_TCP */#if LWIP_UDP && LWIP_UDPLITE/* Level: IPPROTO_UDPLITE */ case IPPROTO_UDPLITE: if (optlen < sizeof(int)) { err = EINVAL; break; } /* If this is no UDP lite socket, ignore any options. */ if (sock->conn->type != NETCONN_UDPLITE) return 0; switch (optname) { case UDPLITE_SEND_CSCOV: case UDPLITE_RECV_CSCOV: break; default: LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", s, optname)); err = ENOPROTOOPT; } /* switch (optname) */ break;#endif /* LWIP_UDP && LWIP_UDPLITE *//* UNDEFINED LEVEL */ default: LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname)); err = ENOPROTOOPT; } /* switch (level) */ if (err != ERR_OK) { sock_set_errno(sock, err); return -1; } /* Now do the actual option processing */ data.sock = sock;#ifdef LWIP_DEBUG data.s = s;#endif /* LWIP_DEBUG */ data.level = level; data.optname = optname; data.optval = (void*)optval; data.optlen = &optlen; data.err = err; tcpip_callback(lwip_setsockopt_internal, &data); sys_arch_sem_wait(&sock->conn->op_completed, 0); /* maybe lwip_setsockopt_internal has changed err */ err = data.err; sock_set_errno(sock, err); return err ? -1 : 0;}static voidlwip_setsockopt_internal(void *arg){ struct lwip_sock *sock;#ifdef LWIP_DEBUG int s;#endif /* LWIP_DEBUG */ int level, optname; const void *optval; struct lwip_setgetsockopt_data *data; LWIP_ASSERT("arg != NULL", arg != NULL); data = (struct lwip_setgetsockopt_data*)arg; sock = data->sock;#ifdef LWIP_DEBUG s = data->s;#endif /* LWIP_DEBUG */ level = data->level; optname = data->optname; optval = data->optval; switch (level) {/* Level: SOL_SOCKET */ case SOL_SOCKET: switch (optname) { /* The option flags */ case SO_BROADCAST: /* UNIMPL case SO_DEBUG: */ /* UNIMPL case SO_DONTROUTE: */ case SO_KEEPALIVE: /* UNIMPL case SO_OOBINCLUDE: */#if SO_REUSE case SO_REUSEADDR: case SO_REUSEPORT:#endif /* SO_REUSE */ /* UNIMPL case SO_USELOOPBACK: */ if (*(int*)optval) { sock->conn->pcb.ip->so_options |= optname; } else { sock->conn->pcb.ip->so_options &= ~optname; } LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", s, optname, (*(int*)optval?"on":"off"))); break;#if LWIP_SO_RCVTIMEO case SO_RCVTIMEO: netconn_set_recvtimeout(sock->conn, *(int*)optval); break;#endif /* LWIP_SO_RCVTIMEO */#if LWIP_SO_RCVBUF case SO_RCVBUF: netconn_set_recvbufsize(sock->conn, *(int*)optval); break;#endif /* LWIP_SO_RCVBUF */#if LWIP_UDP case SO_NO_CHECK: if (*(int*)optval) { udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_NOCHKSUM); } else { udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_NOCHKSUM); } break;#endif /* LWIP_UDP */ default: LWIP_ASSERT("unhandled optname", 0); break; } /* switch (optname) */ break;/* Level: IPPROTO_IP */ case IPPROTO_IP: switch (optname) { case IP_TTL: sock->conn->pcb.ip->ttl = (u8_t)(*(int*)optval); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %d\n", s, sock->conn->pcb.ip->ttl)); break; case IP_TOS: sock->conn->pcb.ip->tos = (u8_t)(*(int*)optval); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n", s, sock->conn->pcb.ip->tos)); break;#if LWIP_IGMP case IP_MULTICAST_TTL: sock->conn->pcb.udp->ttl = (u8_t)(*(u8_t*)optval); break; case IP_MULTICAST_IF: inet_addr_to_ipaddr(&sock->conn->pcb.udp->multicast_ip, (struct in_addr*)optval); break; case IP_MULTICAST_LOOP: if (*(u8_t*)optval) { udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_MULTICAST_LOOP); } else { udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_MULTICAST_LOOP); } break; case IP_ADD_MEMBERSHIP: case IP_DROP_MEMBERSHIP: { /* If this is a TCP or a RAW socket, ignore these options. */ struct ip_mreq *imr = (struct ip_mreq *)optval; ip_addr_t if_addr; ip_addr_t multi_addr; inet_addr_to_ipaddr(&if_addr, &imr->imr_interface); inet_addr_to_ipaddr(&multi_addr, &imr->imr_multiaddr); if(optname == IP_ADD_MEMBERSHIP){ data->err = igmp_joingroup(&if_addr, &multi_addr); } else { data->err = igmp_leavegroup(&if_addr, &multi_addr); } if(data->err != ERR_OK) { data->err = EADDRNOTAVAIL; } } break;#endif /* LWIP_IGMP */ default: LWIP_ASSERT("unhandled optname", 0); break; } /* switch (optname) */ break;#if LWIP_TCP/* Level: IPPROTO_TCP */ case IPPROTO_TCP: switch (optname) { case TCP_NODELAY: if (*(int*)optval) { tcp_nagle_disable(sock->conn->pcb.tcp); } else { tcp_nagle_enable(sock->conn->pcb.tcp); } LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", s, (*(int *)optval)?"on":"off") ); break; case TCP_KEEPALIVE: sock->conn->pcb.tcp->keep_idle = (u32_t)(*(int*)optval); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %"U32_F"\n", s, sock->conn->pcb.tcp->keep_idle)); break;#if LWIP_TCP_KEEPALIVE case TCP_KEEPIDLE: sock->conn->pcb.tcp->keep_idle = 1000*(u32_t)(*(int*)optval); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %"U32_F"\n", s, sock->conn->pcb.tcp->keep_idle)); break; case TCP_KEEPINTVL: sock->conn->pcb.tcp->keep_intvl = 1000*(u32_t)(*(int*)optval); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %"U32_F"\n", s, sock->conn->pcb.tcp->keep_intvl)); break; case TCP_KEEPCNT: sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(int*)optval); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %"U32_F"\n", s, sock->conn->pcb.tcp->keep_cnt)); break;#endif /* LWIP_TCP_KEEPALIVE *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -