📄 sockopt.c
字号:
/*-------------------------------------------------------------------*/ if (!Net.Initialized) { NetError(NULL, ENETDOWN); return -1; } /*-------------------------------------------------------------------*/ /* Check for valid socket ID. */ /*-------------------------------------------------------------------*/ if (InvalidHandle(s)) { NetError(NULL, ENOTSOCK); return -1; } /*-------------------------------------------------------------------*/ /* Check that the option is accessible and its length is correct. */ /*-------------------------------------------------------------------*/ if (((optname != SO_CALLBACK) && (oval == NULL)) || ((optname == SO_LINGER) && (olen != sizeof(struct linger))) || ((optname != SO_LINGER) && (olen != sizeof(int)))) { NetError(sock, EFAULT); return -1; } /*-------------------------------------------------------------------*/ /* Verify protocol level and option name consistency */ /*-------------------------------------------------------------------*/ if (level == IPPROTO_TCP) { if (optname != TCP_NODELAY) { NetError(sock, ENOPROTOOPT); return -1; } } else if (level != SOL_SOCKET) { NetError(sock, ENOPROTOOPT); return -1; }#endif /*-------------------------------------------------------------------*/ /* Gain exclusive socket API and stack internals access. */ /*-------------------------------------------------------------------*/ if (semPend(sock->api_access, WAIT_FOREVER)) { NetError(NULL, ENOTSOCK); return -1; } semPend(Net.IntSem, WAIT_FOREVER); /*-------------------------------------------------------------------*/ /* Determine which option is requested. */ /*-------------------------------------------------------------------*/ switch (optname) { case SO_BROADCAST: /*---------------------------------------------------------------*/ /* Verify that socket type is UDP. */ /*---------------------------------------------------------------*/ if (sock->type != SOCK_DGRAM) { rc = -1; NetError(sock, EOPNOTSUPP); break; } /*---------------------------------------------------------------*/ /* Set UDP broadcast option. */ /*---------------------------------------------------------------*/ if (*(int *)oval) sock->flags |= SF_BROADCAST; else sock->flags &= ~SF_BROADCAST; break; case SO_NOCHECKSUM: /*---------------------------------------------------------------*/ /* Verify that socket type is UDP. */ /*---------------------------------------------------------------*/ if (sock->type != SOCK_DGRAM) { rc = -1; NetError(sock, EOPNOTSUPP); break; } /*---------------------------------------------------------------*/ /* Set UDP checksum option. */ /*---------------------------------------------------------------*/ if (*(int *)oval) sock->flags |= SF_NOCHECKSUM; else sock->flags &= ~SF_NOCHECKSUM; break; case SO_CALLBACK: { sock->report = *(void (*)(int socket, ui32 events))oval; break; } case SO_CONTIMEO: { int timeo = *(int *)oval; /*---------------------------------------------------------------*/ /* Determine connect() timeout setting with 75 sec minimum. */ /*---------------------------------------------------------------*/ if (timeo < 75000) timeo = 75000; sock->connect_timeo = Ms2Ticks(timeo); break; } case SO_TOS: /*---------------------------------------------------------------*/ /* Assign the type of service setting. */ /*---------------------------------------------------------------*/ sock->ip_tos = *(int *)oval; break; case SO_DONTROUTE: /*---------------------------------------------------------------*/ /* Set dont-route option. */ /*---------------------------------------------------------------*/ if (*(int *)oval) sock->flags |= SF_DONTROUTE; else sock->flags &= ~SF_DONTROUTE; break; case SO_KEEPALIVE: /*---------------------------------------------------------------*/ /* Verify that socket type is TCP. */ /*---------------------------------------------------------------*/ if (sock->type != SOCK_STREAM) { rc = -1; NetError(sock, EOPNOTSUPP); break; } /*---------------------------------------------------------------*/ /* Verify that socket is connected. */ /*---------------------------------------------------------------*/ if ((sock->flags & SF_CONNECTED) == FALSE) { rc = -1; NetError(sock, ENOTCONN); break; } /*---------------------------------------------------------------*/ /* Set keep-alive option. */ /*---------------------------------------------------------------*/ if (*(int *)oval) sock->flags |= SF_KEEPALIVE; else { sock->flags &= ~SF_KEEPALIVE; if (sock->state == SS_ESTABLISHED) NetTimerStop(&sock->state_tmr); } break; case SO_LINGER: { struct linger *lp = oval; /*---------------------------------------------------------------*/ /* Verify that socket type is TCP. */ /*---------------------------------------------------------------*/ if (sock->type != SOCK_STREAM) { rc = -1; NetError(sock, EOPNOTSUPP); break; } /*---------------------------------------------------------------*/ /* If requested, disable linger on close and forceful close. */ /*---------------------------------------------------------------*/ if (lp->l_onoff == FALSE) { sock->flags &= ~(SF_LINGER | SF_FORCEFUL); } /*---------------------------------------------------------------*/ /* Else enable linger and determine forceful close setting. */ /*---------------------------------------------------------------*/ else { sock->flags |= SF_LINGER; if (lp->l_linger) sock->flags &= ~SF_FORCEFUL; else sock->flags |= SF_FORCEFUL; } break; } case SO_OOBINLINE: /*---------------------------------------------------------------*/ /* Verify that socket type is TCP. */ /*---------------------------------------------------------------*/ if (sock->type != SOCK_STREAM) { rc = -1; NetError(sock, EOPNOTSUPP); break; } /*---------------------------------------------------------------*/ /* Determine OOB data left in-line setting. */ /*---------------------------------------------------------------*/ if (*(int *)oval) sock->flags |= SF_INLINE; else sock->flags &= ~SF_INLINE; break; case SO_RCVBUF: /*---------------------------------------------------------------*/ /* Verify that socket type is TCP. */ /*---------------------------------------------------------------*/ if (sock->type != SOCK_STREAM) { rc = -1; NetError(sock, EOPNOTSUPP); break; } break; case SO_RCVTIMEO: { int timeo = *(int *)oval; /*---------------------------------------------------------------*/ /* Determine receive() timeout setting with 500 ms minimum. */ /*---------------------------------------------------------------*/ if (timeo < 500) timeo = 500; sock->recv_timeo = Ms2Ticks(timeo); break; } case SO_REUSEADDR: /*---------------------------------------------------------------*/ /* Determine local address re-use setting. */ /*---------------------------------------------------------------*/ if (*(int *)oval) sock->flags |= SF_REUSEADDR; else sock->flags &= ~SF_REUSEADDR; break; case SO_SNDBUF: /*---------------------------------------------------------------*/ /* Verify that socket type is TCP. */ /*---------------------------------------------------------------*/ if (sock->type != SOCK_STREAM) { rc = -1; NetError(sock, EOPNOTSUPP); break; } break; case SO_SNDTIMEO: { int timeo = *(int *)oval; /*---------------------------------------------------------------*/ /* Determine send() timeout setting with 500 ms minimum. */ /*---------------------------------------------------------------*/ if (timeo < 500) timeo = 500; sock->send_timeo = Ms2Ticks(timeo); break; } case TCP_NODELAY: /*---------------------------------------------------------------*/ /* Verify that socket type is TCP. */ /*---------------------------------------------------------------*/ if (sock->type != SOCK_STREAM) { rc = -1; NetError(sock, EOPNOTSUPP); break; } /*---------------------------------------------------------------*/ /* Determine whether Nagle's algorithm is to be disabled. */ /*---------------------------------------------------------------*/ if (*(int *)oval) sock->flags |= SF_NODELAY; else sock->flags &= ~SF_NODELAY; break; default: rc = -1; NetError(sock, ENOPROTOOPT); break; } /*-------------------------------------------------------------------*/ /* Release exclusive API and internals access. */ /*-------------------------------------------------------------------*/ semPost(sock->api_access); semPost(Net.IntSem); return rc;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -