inet_drv.c

来自「OTP是开放电信平台的简称」· C语言 代码 · 共 2,233 行 · 第 1/5 页

C
2,233
字号
/* ``The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved via the world wide web at http://www.erlang.org/. *  * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. *  * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' * * The SCTP protocol was added 2006 * by Leonid Timochouk <l.timochouk@gmail.com> * and Serge Aleynikov  <serge@hq.idt.net> * at IDT Corp. Adapted by the OTP team at Ericsson AB. *  *     $Id$ */#ifdef HAVE_CONFIG_H#include "config.h"#endif/* If we HAVE_SCTP_H and Solaris, we need to define the following in   order to get SCTP working:*/#if (defined(HAVE_SCTP_H) && defined(__sun) && defined(__SVR4))#define  SOLARIS10    1/* WARNING: This is not quite correct, it may also be Solaris 11! */#define  _XPG4_2#define  __EXTENSIONS__#endif#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <sys/types.h>#include <errno.h>#ifndef _OSE_#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_SYS_UIO_H#include <sys/uio.h>#endif#endif/* use http processing */#define USE_HTTP /* All platforms fail on malloc errors. */#define FATAL_MALLOC#include "erl_driver.h"#ifdef __WIN32__#define  STRNCASECMP strncasecmp#define INCL_WINSOCK_API_TYPEDEFS 1#ifndef WINDOWS_H_INCLUDES_WINSOCK2_H#include <winsock2.h>#endif#include <windows.h>#include <Ws2tcpip.h>   /* NEED VC 6.0 !!! */#undef WANT_NONBLOCKING#include "sys.h"#undef EWOULDBLOCK#undef ETIMEDOUT#define HAVE_MULTICAST_SUPPORT#define ERRNO_BLOCK             WSAEWOULDBLOCK#define EWOULDBLOCK             WSAEWOULDBLOCK#define EINPROGRESS             WSAEINPROGRESS#define EALREADY                WSAEALREADY#define ENOTSOCK                WSAENOTSOCK#define EDESTADDRREQ            WSAEDESTADDRREQ#define EMSGSIZE                WSAEMSGSIZE#define EPROTOTYPE              WSAEPROTOTYPE#define ENOPROTOOPT             WSAENOPROTOOPT#define EPROTONOSUPPORT         WSAEPROTONOSUPPORT#define ESOCKTNOSUPPORT         WSAESOCKTNOSUPPORT#define EOPNOTSUPP              WSAEOPNOTSUPP#define EPFNOSUPPORT            WSAEPFNOSUPPORT#define EAFNOSUPPORT            WSAEAFNOSUPPORT#define EADDRINUSE              WSAEADDRINUSE#define EADDRNOTAVAIL           WSAEADDRNOTAVAIL#define ENETDOWN                WSAENETDOWN#define ENETUNREACH             WSAENETUNREACH#define ENETRESET               WSAENETRESET#define ECONNABORTED            WSAECONNABORTED#define ECONNRESET              WSAECONNRESET#define ENOBUFS                 WSAENOBUFS#define EISCONN                 WSAEISCONN#define ENOTCONN                WSAENOTCONN#define ESHUTDOWN               WSAESHUTDOWN#define ETOOMANYREFS            WSAETOOMANYREFS#define ETIMEDOUT               WSAETIMEDOUT#define ECONNREFUSED            WSAECONNREFUSED#define ELOOP                   WSAELOOP#undef ENAMETOOLONG#define ENAMETOOLONG            WSAENAMETOOLONG#define EHOSTDOWN               WSAEHOSTDOWN#define EHOSTUNREACH            WSAEHOSTUNREACH#undef ENOTEMPTY#define ENOTEMPTY               WSAENOTEMPTY#define EPROCLIM                WSAEPROCLIM#define EUSERS                  WSAEUSERS#define EDQUOT                  WSAEDQUOT#define ESTALE                  WSAESTALE#define EREMOTE                 WSAEREMOTE#define INVALID_EVENT           WSA_INVALID_EVENTstatic BOOL (WINAPI *fpSetHandleInformation)(HANDLE,DWORD,DWORD);#define sock_open(af, type, proto) \    make_noninheritable_handle(socket((af), (type), (proto)))#define sock_close(s)              closesocket((s))#define sock_shutdown(s, how)      shutdown((s), (how))#define sock_accept(s, addr, len) \    make_noninheritable_handle(accept((s), (addr), (len)))#define sock_connect(s, addr, len) connect((s), (addr), (len))#define sock_listen(s, b)          listen((s), (b))#define sock_bind(s, addr, len)    bind((s), (addr), (len))#define sock_getopt(s,t,n,v,l)     getsockopt((s),(t),(n),(v),(l))#define sock_setopt(s,t,n,v,l)     setsockopt((s),(t),(n),(v),(l))#define sock_name(s, addr, len)    getsockname((s), (addr), (len))#define sock_peer(s, addr, len)    getpeername((s), (addr), (len))#define sock_ntohs(x)              ntohs((x))#define sock_ntohl(x)              ntohl((x))#define sock_htons(x)              htons((x))#define sock_htonl(x)              htonl((x))#define sock_send(s,buf,len,flag)  send((s),(buf),(len),(flag))#define sock_sendv(s, vec, size, np, flag) \                WSASend((s),(WSABUF*)(vec),\				   (size),(np),(flag),NULL,NULL)#define sock_recv(s,buf,len,flag)  recv((s),(buf),(len),(flag))#define sock_recvfrom(s,buf,blen,flag,addr,alen) \                recvfrom((s),(buf),(blen),(flag),(addr),(alen))#define sock_sendto(s,buf,blen,flag,addr,alen) \                sendto((s),(buf),(blen),(flag),(addr),(alen))#define sock_hostname(buf, len)    gethostname((buf), (len))#define sock_getservbyname(name,proto) getservbyname((name),(proto))#define sock_getservbyport(port,proto) getservbyport((port),(proto))#define sock_errno() WSAGetLastError()#define sock_create_event(d)       WSACreateEvent()#define sock_close_event(e)        WSACloseEvent(e)#define sock_select(D, Flags, OnOff) winsock_event_select(D, Flags, OnOff)#define SET_BLOCKING(s)           ioctlsocket(s, FIONBIO, &zero_value)#define SET_NONBLOCKING(s)        ioctlsocket(s, FIONBIO, &one_value)static unsigned long zero_value = 0;static unsigned long one_value = 1;#else#ifdef VXWORKS#include <sockLib.h>#include <sys/times.h>#include <iosLib.h>#include <taskLib.h>#include <selectLib.h>#include <ioLib.h>#else#include <sys/time.h>#ifdef NETDB_H_NEEDS_IN_H#include <netinet/in.h>#endif#include <netdb.h>#endif#ifndef _OSE_#include <sys/socket.h>#include <netinet/in.h>#else/* datatypes and macros from Solaris socket.h */struct  linger {        int     l_onoff;                /* option on/off */        int     l_linger;               /* linger time */};#define SO_OOBINLINE    0x0100          /* leave received OOB data in line */#define SO_LINGER       0x0080          /* linger on close if data present */#endif#ifdef VXWORKS#include <rpc/rpctypes.h>#endif#ifdef DEF_INADDR_LOOPBACK_IN_RPC_TYPES_H#include <rpc/types.h>#endif#ifndef _OSE_#include <netinet/tcp.h>#include <arpa/inet.h>#endif#if (!defined(VXWORKS) && !defined(_OSE_))#include <sys/param.h>#ifdef HAVE_ARPA_NAMESER_H#include <arpa/nameser.h>#endif#endif#ifdef HAVE_SYS_SOCKIO_H#include <sys/sockio.h>#endif#ifdef HAVE_SYS_IOCTL_H#include <sys/ioctl.h>#endif#ifndef _OSE_#include <net/if.h>#else#define IFF_MULTICAST 0x00000800#endif#ifdef _OSE_#include "inet.h"#include "ineterr.h"#include "ose_inet_drv.h"#include "nameser.h" #include "resolv.h"#define SET_ASYNC(s) setsockopt((s), SOL_SOCKET, SO_OSEEVENT, (&(s)), sizeof(int))extern void select_release(void);#endif /* _OSE_ *//* Solaris headers, only to be used with SFK */#ifdef _OSE_SFK_#include <ctype.h>#include <string.h>#endif/* SCTP support -- currently for UNIX platforms only: */#undef HAVE_SCTP#if (!defined(VXWORKS) && !defined(_OSE_) && !defined(__WIN32__) && defined(HAVE_SCTP_H))#include <netinet/sctp.h>/* SCTP Socket API Draft from version 11 on specifies that netinet/sctp.h must   explicitly define HAVE_SCTP in case when SCTP is supported,  but Solaris 10   still apparently uses Draft 10, and does not define that symbol, so we have   to define it explicitly:*/#ifndef     HAVE_SCTP#    define HAVE_SCTP#endif/* These changed in draft 11, so SOLARIS10 uses the old MSG_* */#if ! HAVE_DECL_SCTP_UNORDERED#     define    SCTP_UNORDERED  MSG_UNORDERED#endif#if ! HAVE_DECL_SCTP_ADDR_OVER#     define    SCTP_ADDR_OVER  MSG_ADDR_OVER#endif#if ! HAVE_DECL_SCTP_ABORT#     define    SCTP_ABORT      MSG_ABORT#endif#if ! HAVE_DECL_SCTP_EOF#     define    SCTP_EOF        MSG_EOF#endif#endif /* SCTP supported */#ifndef WANT_NONBLOCKING#define WANT_NONBLOCKING#endif#include "sys.h"/* #define INET_DRV_DEBUG 1 */#ifdef INET_DRV_DEBUG#define DEBUG 1#undef DEBUGF#define DEBUGF(X) printf X#endif#if !defined(__WIN32__) && !defined(HAVE_STRNCASECMP)#define STRNCASECMP my_strncasecmpstatic int my_strncasecmp(const char *s1, const char *s2, size_t n){    int i;    for (i=0;i<n-1 && s1[i] && s2[i] && toupper(s1[i]) == toupper(s2[i]);++i)	;    return (toupper(s1[i]) - toupper(s2[i]));}	#else#define  STRNCASECMP strncasecmp#endif#define INVALID_SOCKET -1#define INVALID_EVENT  -1#define SOCKET_ERROR   -1#define SOCKET int#define HANDLE long int#define FD_READ    DO_READ#define FD_WRITE   DO_WRITE#define FD_CLOSE   0#define FD_CONNECT DO_WRITE#define FD_ACCEPT  DO_READ#define sock_connect(s, addr, len)  connect((s), (addr), (len))#define sock_listen(s, b)           listen((s), (b))#define sock_bind(s, addr, len)     bind((s), (addr), (len))#ifdef VXWORKS#define sock_getopt(s,t,n,v,l)      wrap_sockopt(&getsockopt,\                                                 s,t,n,v,(unsigned int)(l))#define sock_setopt(s,t,n,v,l)      wrap_sockopt(&setsockopt,\                                                 s,t,n,v,(unsigned int)(l))#else#define sock_getopt(s,t,n,v,l)      getsockopt((s),(t),(n),(v),(l))#define sock_setopt(s,t,n,v,l)      setsockopt((s),(t),(n),(v),(l))#endif#define sock_name(s, addr, len)     getsockname((s), (addr), (len))#define sock_peer(s, addr, len)     getpeername((s), (addr), (len))#define sock_ntohs(x)               ntohs((x))#define sock_ntohl(x)               ntohl((x))#define sock_htons(x)               htons((x))#define sock_htonl(x)               htonl((x))#ifdef _OSE_#define sock_accept(s, addr, len)   ose_inet_accept((s), (addr), (len))#define sock_send(s,buf,len,flag)   ose_inet_send((s),(buf),(len),(flag))#define sock_sendto(s,buf,blen,flag,addr,alen) \                ose_inet_sendto((s),(buf),(blen),(flag),(addr),(alen))#define sock_sendv(s, vec, size, np, flag) \		(*(np) = ose_inet_sendv((s), (SysIOVec*)(vec), (size)))#define sock_open(af, type, proto)  ose_inet_socket((af), (type), (proto))#define sock_close(s)               ose_inet_close((s))#define sock_hostname(buf, len)     ose_gethostname((buf), (len))#define sock_getservbyname(name,proto) ose_getservbyname((name), (proto))#define sock_getservbyport(port,proto) ose_getservbyport((port), (proto))#else#define sock_accept(s, addr, len)   accept((s), (addr), (len))#define sock_send(s,buf,len,flag)   send((s),(buf),(len),(flag))#define sock_sendto(s,buf,blen,flag,addr,alen) \                sendto((s),(buf),(blen),(flag),(addr),(alen))#define sock_sendv(s, vec, size, np, flag) \		(*(np) = writev((s), (struct iovec*)(vec), (size)))#define sock_sendmsg(s,msghdr,flag) sendmsg((s),(msghdr),(flag))#define sock_open(af, type, proto)  socket((af), (type), (proto))#define sock_close(s)               close((s))#define sock_shutdown(s, how)       shutdown((s), (how))#define sock_hostname(buf, len)     gethostname((buf), (len))#define sock_getservbyname(name,proto) getservbyname((name), (proto))#define sock_getservbyport(port,proto) getservbyport((port), (proto))#endif /* _OSE_ */#define sock_recv(s,buf,len,flag)   recv((s),(buf),(len),(flag))#define sock_recvfrom(s,buf,blen,flag,addr,alen) \                recvfrom((s),(buf),(blen),(flag),(addr),(alen))#define sock_recvmsg(s,msghdr,flag) recvmsg((s),(msghdr),(flag))#define sock_errno()                errno#define sock_create_event(d)        ((d)->s) /* return file descriptor */#define sock_close_event(e)                  /* do nothing */#ifdef _OSE_#define inet_driver_select(port, e, mode, on) \                                    ose_inet_select(port, e, mode, on)#else#define inet_driver_select(port, e, mode, on) \                                    driver_select(port, e, mode, on)#endif /* _OSE_ */#define sock_select(d, flags, onoff) do { \        (d)->event_mask = (onoff) ? \                 ((d)->event_mask | (flags)) : \                 ((d)->event_mask & ~(flags)); \        DEBUGF(("sock_select(%ld): flags=%02X, onoff=%d, event_mask=%02lX\r\n", 		(long) (d)->port, (flags), (onoff), (unsigned long) (d)->event_mask)); \        inet_driver_select((d)->port, (ErlDrvEvent)(long)(d)->event, (flags), (onoff)); \   } while(0)#endif /* __WIN32__ */#define get_int24(s) ((((unsigned char*) (s))[0] << 16) | \                      (((unsigned char*) (s))[1] << 8)  | \                      (((unsigned char*) (s))[2]))#define get_little_int32(s) ((((unsigned char*) (s))[3] << 24) | \			     (((unsigned char*) (s))[2] << 16)  | \			     (((unsigned char*) (s))[1] << 8) | \			     (((unsigned char*) (s))[0]))/*----------------------------------------------------------------------------** Interface constants.** ** This section must be "identical" to the corresponding inet_int.hrl*//* general address encode/decode tag */#define INET_AF_INET        1#define INET_AF_INET6       2#define INET_AF_ANY         3 /* INADDR_ANY or IN6ADDR_ANY_INIT */#define INET_AF_LOOPBACK    4 /* INADDR_LOOPBACK or IN6ADDR_LOOPBACK_INIT *//* INET_REQ_GETTYPE enumeration */#define INET_TYPE_STREAM    1#define INET_TYPE_DGRAM     2#define INET_TYPE_SEQPACKET 3/* INET_LOPT_MODE options */#define INET_MODE_LIST      0#define INET_MODE_BINARY    1/* INET_LOPT_DELIVER options */#define INET_DELIVER_PORT   0#define INET_DELIVER_TERM   1/* INET_LOPT_ACTIVE options */#define INET_PASSIVE        0  /* false */#define INET_ACTIVE         1  /* true */#define INET_ONCE           2  /* true; active once then passive *//* INET_REQ_GETSTATUS enumeration */#define INET_F_OPEN         0x0001#define INET_F_BOUND        0x0002#define INET_F_ACTIVE       0x0004#define INET_F_LISTEN       0x0008#define INET_F_CON          0x0010

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?