⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sockets.c

📁 lwip-1.4.0
💻 C
📖 第 1 页 / 共 5 页
字号:
      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 + -