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 + -
显示快捷键?