From towfiq@ftp.com Mon Jan 27 11:56:44 1992 Sender: winsockapi-request@ftp.com Date: Thu, 21 Nov 91 13:52:20 -0500 From: towfiq@ftp.com (Mark Towfiq) To: winsockapi@ftp.com Subject: Draft Revision 1.1 Hot off the press from Martin: ---------- WinSockAPI ---------- ---------------------------------------------------------- A Berkeley Sockets API Specification for Microsoft Windows ---------------------------------------------------------- Draft Revision 1.1 November 19 1991 WinSockAPI Committee Moderator: Martin Hall Coordinator: Mark Towfiq JSB Corporation FTP Software Inc 108 Whispering Pines Drive 26 Princess Street Suite 115 Wakefield Scotts Valley MA 01880 CA 95066 USA USA Tel: (408) 438-8300 Tel: (617) 246-0900 Fax: (408) 438-8360 Fax: (617) 246-0901 ------------ INTRODUCTION ------------ This specification defines a standard and consistent Berkeley Socket-style API for Microsoft Windows. It encompasses both familiar socket style routines and some Microsoft Windows-specific extensions designed to allow the programmer to take advantage of the message driven nature of Microsoft Windows and to obviate the need for polled I/O. The intention of this specification is to define a set of routines with common entry points contained in a Microsoft Windows Dynamic Link Library (DLL). Each appropriate network software vendor can thus provide their own implementation according to this. This enables application software developers to write to the standard thus doing away with the need for time-consuming network "ports" to each vendor's API. Vendors whose API conforms to this specification will be termed "WinSockAPI-compliant". To be WinSockAPI-compliant, a vendor's API will provide all the functions and functionality specified here including the MS-Windows-specific enhancements. ------------------ HISTORY & WORKINGS ------------------ The WinSockAPI Committee is a body of people formed at a Birds of a Feather Session held at Interop '91 in San Jose on October 10. A committee was established with a view to resolving the specification in as short a time frame as possible. This specification will be circulated electronically on the Internet to enable comments from as wide an audience as possible. Appropriate changes will then be made to the specification in advance of each (?) committee meeting. ------------------ Committee Meetings ------------------ December 9. Microsoft Corp, Redmond, WA COMMITTEE MEMBERS Martin Hall (Moderator) JSB Corp. martinh@jsbus.com mh@jsb.co.uk Mark Towfiq (Coordinator) FTP Software towfiq@ftp.com Carl Beame Beame & Whiteside beame@mcmaster.ca Hoek Law Citicorp law@dcc.tti.com Brad Rice Age rice@age.com James Van Bokkelen FTP Software jbvb@ftp.com Gary M. Gere Gupta ggere@gupta.com Bill Hayes Hewlett Packard billh@hpchdpc.cnd.hp.com Graeme Le Roux Moresdawn P/L fax. +612-968-1544 Lee Murach Network Research lee@nrc.com Alistair Banks Microsoft alistair@microsoft.com Henry Sanders Microsoft henrysa@microsoft.com Nelson Bolyard SGI nelson@sgi.com David Pool SPRY Inc Geoff Arnold Sun Microsystems geoff@east.sun.com Miles Wu Wollongong long@twg.com Allen Rochkind 3Com Corp Boris Yanovsky NetManage Inc boris@netmanage.com Amatzia BenArtzi NetManage Inc amatzia@netmanage.com ---------------- REVISION HISTORY ---------------- 1.0 --- Most of the issues discussed below have been folded into the specification. The issues marked "NOT CONCLUDED" remain unresolved. They require further community examination and "face-to-face" discussion at the next committee meeting: Summary of Changes ------------------ Addition of inet_ntoa(), inet_addr() and rresvport() functions. Appropriate changes to WINSOCK.DEF file definition. Changes to errno definitions (exclusion of some, inclusion of others) Extensions to SelectWindow() functionality Explicit discussion of how the various WinSockAPI components are made available. Definition of options to be supported under certain routines. Key Issues ---------- Several key issues emerged from discussion of Revision 1.0. These were: 1. Errno's 1.1 Problems with ERRNO definitions (CONCLUDED) The consensus of opinion here seemed to be (i) Avoid potential clashes with Microsoft and Borland errno's (add 1000 to equivalent BSD definition) (ii) Provide errno definition extensibility. (iii) Justify inclusion of non-BSD errno's (iv) Resolve EINVAL/EBADF clashes between Microsoft and Borland C. The suggestion was to provide a WinSockAPI version of this. i.e. to introduce a new set of variables which are WinSockAPI versions which resolve clashes. This has been done (see Errnos below). 1.2 Setting of errno for examination by application code.(NOT CONCLUDED) Several suggestions emerged for resolving this issue. They were (i) Embed the errno as the return value (ii) Extend (change) the socket() call to take an additional paramater which is a pointer to the integer into which your application wishes to receive errno values. (iii) Introduce an errno() call. (iv) Introduce a new variable (e.g. winsock_errno) which is part of the per-process DLL data. (v) Ensure every API function takes an additional paramater (int far *lpErrno), which is invisible to the programmer by virtue of #define's for each function. e.g. the vendor's DLL function could be: WinSocket(a,b,c,lpErrno) The programmer calls the function as socket(a,b,c) which is preprocessed by virtue of: #define socket(a,b,c) WinSocket(a,b,c,&errno). (i) should be discarded because it's insufficiently compatible with BSD style. The same goes for option (iv).The debate seemed to come down to one of (ii) and (iii). Option (v) whilst at first sight perhaps appearing cumbersome does have the virtue of not requiring deviation from BSD-compatible source code. 2. SelectWindow() (CONCLUDED) This was generally welcomed but generated some positive discussion regarding: 2.1 Deluge of messages 2.2 Extensions over and above standard select() call to include explicit notification of completed connections, accepted connections and closed sockets. 2.3 Provision for 32-bit Windows. All of the above are catered for in extensions folded in within this revision (1.1). 2.4 Turn off message-based notification. 2.5 Provision for full application message queues 3. Inclusion/exclusion of certain inet_xxx functions.(CONCLUDED) The general consensus was that only the inet_ntoa() and inet_addr() functions were necessary. The specification has changed accordingly. 4. How to implement getxbyy functions given data volatility and forthcoming pre-emptive versions of Windows. (NOT CONCLUDED) This issue continues to produce substantial discussion without real conclusion. If the specification limited itself to existing versions of non-preemptive, single threaded Windows then it would simply be a question of implementing BSD compatibility and perhaps riding with the issues of fixed data areas thus required. However, this specification can and should be cogniscent of preemptive, multi-threaded Windows just around the corner. To this end, BSD conformant implementation of the getxbyy() functions looks increasingly unwieldy and unrealistic. This issue should undoubtedly have more discussion within the community and the committee. 5. Extensions to standard .DEF file definitions to embrace consolidated API function list. (CONCLUDED) These changes have been made as appropriate. 6. Discussion of blocking calls. This centred on what and how blocking calls should be implemented, what place they have generally and how a multi-threaded Windows environment might impact on the design criteria. This issue created fairly animated debate. A whole host of issues were generated such as whether to introduce a call to unblock a blocked call (e.g. cancel()). (NOT CONCLUDED) 7. Desire for initial specification to include Win32 source code compatibility as an aim. This is a general subject which has seen relevance in numerous conversations. It must be explicitly addressed and resolved. For maximum future compatibility and minimum future fuss this should undoubtedly be a major design consideration. (CONCLUDED) 8. Desirability of readsocket(), writesocket() functions being included. These would be no different to send() and recv(). Given that existing code which uses socket-based read() and write() routines would have to be changed anyway it seems to make sense to keep the number of functions down so they may as well be changed to recv() and send(). Hence readsocket() and writesocket() have not been added. (CONCLUDED) 9. National Language support for error strings.(CONCLUDED) This specification should definitely not be mandated to resolve national language issues. Detailed errno specification allows for application developers to provide appropriate error messages. Windows itself doesn't prescribe error messages. The WinSockAPI shouldn't either! 10. Need to include a standard prototype for socket.h. This will be done but at a stage at which certain issues such as options for support have been concluded. (NOT CONCLUDED) 11. Discussion of the possibility of including the name resolution routines explicitly led to some consensus that the gethostbyXXX() routines were the right level of functionality. (CONCLUDED) 12. How many sockets should the WINSOCK.DLL support? This should be a network vendor rather than WinSockAPI-compliance issue. We may however want to define a minimum. (NOT CONCLUDED) Summary of Outstanding Issues ----------------------------- How getxbyy() functions should return data How/whether way in which blocking calls are implemented should be mandated. How errno should be returned to application program Inclusion of prototype socket.h Specific discussion of specifics of various routines. It has been proposed that the following needs resolving. The WinSockAPI community should discuss this as a matter of urgency! {get|set}sockopt() SO_DEBUG SO_REUSEADDR SO_KEEPALIVE SO_LINGER SO_BROADCAST SO_OOBINLINE SO_SNDBUF SO_RCVBUF SO_TYPE SO_ERROR fcntl() FIONREAD FIONBIO SIOCSIFADDR SIOCGIFADDR SIOCGIFADDR SIOCSIFDSTADDR SIOCGIFDSTADDR SIOCSIFBRDADDR SIOCGIFBRDADDR SIOCSIFFLAGS SIOCGIFFLAGS SIOCGIFCONF SIOCSIFNERMASK SIOCGIFNERMASK SIOCADDRT SIOCDELRT SIOCSIFMETRIC SIOCGIFMETRIC SIOCGARP SIOCDARP SIOCSARP listen() What is the backlog limit? -------- OVERVIEW -------- This specification is built on a fusion of two existing API's together with considerable discussion: JSB Virtual Socket Library NetManage's Socket Library The specification defines the following: Berkeley Socket DLL Reference including Library Name, Functions & DLL Ordinal Values MS Windows-based extensions Header Files Data Structures Error Numbers ------------------ BERKELEY SOCKET DLL ------------------ Overview --------- This section details the WinSockAPI components and suppliers, Berkeley routines contained within a WinSockAPI-compliant API, together with their relevant DLL ordinal numbers. Components ---------- The proposal from Microsoft is to include this WinSockAPI DEFINITION as a standard part of the Windows API at some future point. At that point, components from Microsoft forming part of the Windows SDK would include: WinSockAPI documentation WinSockAPI import library WinSockAPI header files Each network vendor would then be responsible for supplying: Appropriate network stack A WinSockAPI-compliant WINSOCK.DLL module. Library Name ------------ The DLL name will be WINSOCK.DLL. This DLL has to be made available in some way for a WinSockAPI application to run. It is at the vendors discretion how this is made available. Additionally an import library will be required to resolve DLL-based functions at link time. At this stage it seems likely that this will initially be a network vendor-supplied item also, although later inclusion of this specification as a standard MS Windows API would obviate that requirement. Blocking Sockets ---------------- Blocking socket operations will be supported. Library Routines ---------------- The naming convention adopted for the standard Berkeley routines is to stay as close as possible to the original Berkeley routine. This enables pre-existing code to be ported more easily to the MS Windows environment (e.g. MIT X Server code). Only where library name clashes which cannot be resolved easily occur will a routine name which differs from the Berkeley equivalent be chosen. (e.g. close() appears as closesocket()). int accept(int s, struct sockaddr far * addr, int far *addrlen) int bind(int s, struct sockaddr far * addr, int namelen) bcopy(char far * b1, char far * b2, int length) bcmp(char far *b1, char far *b2, int length) bzero(char far *b, int length) int closesocket(int s) int connect(int s, struct sockaddr far *name, int namelen) int getdomainname(char far *name, int namelen) struct hostent far *gethostent() struct hostent far *gethostbyaddr(char far *addr, int len, int type) struct hostent far *gethostbyname(char far *) void sethostent(int stayopen) struct hostent far *gethostent() void endhostent() long gethostid() int gethostname(char far *name, int namelen) int getpeername(int s, struct sockaddr far *name, int namelen) struct protoent far *getprotoent() struct protoent far *getprotobynumber(int proto) struct protoent far *getprotobyname(char far *name) void setprotoent(int stayopen) void endprotoent() struct servent far *getservent() struct servent far *getservbyport(int port, char far *serv) struct servent far *getservbyname(char far *name, char far *proto) void setservent(int stayopen) void endservent() int getsockname(int s, struct sockaddr far *name, int namelen) int getsockopt(int s, int level, int optname, char far *optval, int far *optlen) int setsockopt(int s, int level, int optname, char far *optval, int optlen) ulong htonl(ulong hostlong) ushort htons(ushort hostshort) ulong ntohl(ulong netlong) ushort ntohs(ushort netshort) int fcntl(int s, int cmd, int arg) char *inet_ntoa(struct in_addr in) struct in_addr inet_addr(char *cp) int listen(int s, int backlog) int recv(int s, char far * buf, int len, int flags) flags MSG_PEEK and/or MSG_OOB int recvfrom(int s, char far *buf, int len, int flags, struct sockaddr far * from, int fromlen) int rresvport() long select(int nfds, fd_set far *readfds, fd_set far * writefds, fd_set far *exceptfds, struct timeval far *timeout) int send(int s, char far *buf, int len, int flags) flags MSG_PEEK and/or MSG_OOB int sendto(int s, char far * buf, int len, int flags, struct sockaddr far *to, int tolen) int shutdown(int s, int how) how 0 disallows further receives 1 disallows further sends 2 disallows further sends and receives. int socket(int af, int type, int protocol) type SOCK_STREAM, SOCK_DGRAM or SOCK_RAW Ordinal Values -------------- Function Name Ordinal Value ----------------------------- accept 1 bind 2 bcopy 3 bcmp 4 bzero 5 closesocket 6 connect 7 getdomainname 8 gethostent 9 gethostbyaddr 10 gethostbyname 11 sethostent 12 gethostent 13 endhostent 14 gethostid 15 gethostname 16 getpeername 17 getprotoent 18 getprotobynumber 19 getprotobyname 20 setprotoent 21 endprotoent 22 getservent 23 getservbyport 24 getservbyname 25 setservent 26 endservent 27 getsockname 28 getsockopt 29 setsockopt 30 htonl 31 htons 32 ntohl 33 ntohs 34 fcntl 35 inet_ntoa 36 inet_addr 37 listen 38 recv 39 recvfrom 40 rresvport 41 select 42 send 43 sendto 44 shutdown 45 socket 46 ---------------------------------- MICROSOFT WINDOWS-BASED EXTENSIONS ---------------------------------- There will be a single Microsoft Windows-style extension to the standard Berkely routines listed above. This additional routine allows a Windows programmer to exploit the message-driven nature of the Windows environment and obviates the need to use polling mechanisms such as select() and non- blocking recv() calls etc. Although implementation of this function by WinSockAPI-compliant implementations is mandatory, it's use by a programmer is not. It will be perfectly possible to implement application solutions which don't exploit this function. It's use, however, will have significant performance benefits. int SelectWindow(int s, HWND hWnd, unsigned int wMsg, long lCondition) #define FD_READ 0x01 #define FD_WRITE 0x02 #define FD_EXCEPT 0x04 #define FD_ACCEPT 0x08 #define FD_CONNECT 0x10 #define FD_CLOSE 0x20 This function mimics the select() function in allowing a program to determine whether a socket is ready for reading, writing or has an exception condition pending on it. Furthermore, it makes functionality inherent in the select() function explicit by allowing for direct and explicit notification of events such as accepted and completed connections. Additionally, an application program can be notified of remote closes on specific sockets. The function states an interest in one or many conditions (lCondition) which occur on socket s. When one of the specified conditions occurs, message wMsg will be posted to the window hWnd. The message posted will contain the socket descriptor in wParam and the condition which generated the message in lParam. Notes The implementation of this function should result in single shot messages for particular events being generated. Thus if a socket becomes ready for reading a single message should be posted to the specified window. Another message should not be sent to the window until an appropriate call such as a recv() has been made. Thus an appropriate call from an application program implicitly reenables messages notifying existence of a previously nominated condition. An application can request that it no longer wants to receive any message-based notification of events by calling SelectWindow() with an lCondition value of 0. Note that for incoming data, notification of its presence and recv() calls issued by an application program do not have to be 1 to 1. In other words, having been notified of the presence of data to be read an application program can make multiple subsequent recv() calls until an EWOULDBLOCK condition is indicated (assuming, of course, that it's a non-blocking socket!). Note also that vendor's implementations of the WinSockAPI specification have to take responsibility for reposting messages that don't arrive in the application due to a full queue. (This may promote discussion of message priority). For further clarification, messages generated by the following conditions are reenabled by the nominated function call: Condition Description Function ---------------------------------------------------------------- FD_READ Socket ready for reading recv() FD_WRITE Socket ready for writing send() FD_EXCEPT Exception on socket Not applicable FD_ACCEPT Socket ready for accept accept() FD_CONNECT Non-blocking connect() completed Not applicable FD_CLOSE Connection closed Not applicable Example ------- Assuming I am interested in readiness for reading on a socket I have created then my code would state it's interest in being notified of this readiness asynchronously by making the following call: SelectWindow(iMySocket, hMyWnd, MY_MESSAGE, FD_READ); An excerpt from window proc might be: case MY_MESSAGE: if (wParam == iMySocket) { if (lParam & FD_READ) { recv(iMySocket, lpMyBuf, BUFFER_SIZE); } } --------------- DATA STRUCTURES --------------- The data structures conform to the Berkeley Socket definition with one key difference: All pointers are FAR. ------------ HEADER FILES ------------ A prototype socket.h will be defined here. ------------ ERROR NUMBERS ------------ The following error numbers will be consistently implemented across all WinSockAPI-compliant implementations. The first set of errno definitions are present to resolve contentions between standard C errno's potentially returned by a socket library but defined inconsistently between various C compilers. #define WSA_EBADF 1009 #define WSA_EINVAL 1022 #define EWOULDBLOCK 1035 #define EINPROGRESS 1036 #define EALREADY 1037 #define ENOTSOCK 1038 #define EDESTADDRREQ 1039 #define EMSGSIZE 1040 #define EPROTOTYPE 1041 #define ENOPROTOOPT 1042 #define EPROTONOSUPPORT 1043 #define ESOCKTNOSUPPORT 1044 #define EOPNOTSUPP 1045 #define EPFNOSUPPORT 1046 #define EAFNOSUPPORT 1047 #define EADDRINUSE 1048 #define EADDRNOTAVAIL 1049 #define ENETDOWN 1050 #define ENETUNREACH 1051 #define ENETRESET 1052 #define ECONNABORTED 1053 #define ECONNRESET 1054 #define ENOBUFS 1055 #define EISCONN 1056 #define ENOTCONN 1057 #define ESHUTDOWN 1058 #define ETOOMANYREFS 1059 #define ETIMEDOUT 1060 #define ECONNREFUSED 1061 #define ELOOP 1062 #define ENAMETOOLONG 1063 #define EHOSTDOWN 1064 #define EHOSTUNREACH 1065 #define ENOTEMPTY 1066 #define EPROCLIM 1067 #define EUSERS 1068 #define EDQUOT 1069 #define ESTALE 1070 #define EREMOTE 1071 From towfiq@ftp.com Mon Jan 27 11:56:57 1992 Sender: winsockapi-request@ftp.com Date: Fri, 10 Jan 92 15:58:19 -0500 From: towfiq@ftp.com (Mark Towfiq) To: winsockapi@ftp.com Subject: [martinh@jsbus.COM: Summary of WinSockAPI spec changes] This is the latest from Martin--as he mentions below, the more detailed spec is on the way, but I think most of the decisions reached at the Dec. meeting are sketched out here. From: martinh@jsbus.COM (Martin Hall) X-Mailer: SCO Portfolio 2.0 Date: Fri, 10 Jan 1992 12:40:08 -0800 (PST) I'd also like to prepend this summary with a list of the December meeting attendees only I don't have it. If you do perhaps you could do that. As I pointed out this is only sketchy... The following summarises changes to the WinSockAPI Specification Version 1.1 based on subsequent email discussion and the committee meeting which took place in Seattle in December. The details of this is currently being worked into a much more detailed specification. The WinSockAPI community will be notified of anticipated completion dates as soon as possible. 1.1 --- Summary of Changes to 1.1 (EMAIL) --------------------------------- Removal of bcopy(), bcmp(), bzero() Confirmation that DLL routines are type PASCAL Confirmation that send/recv sendto/recvfrom will support MSG_PEEK & MSG_OOB listen() - confirmation that backlog limit is implementation-dependent readv/writev() - applications themselves specify the length via msg.msg_iovlen Summary of Changes to 1.1 (COMMITTEE agreement) ----------------------------------------------- SelectWindow() Introduction of errno to lParam Event masking occurs on SelectWindow() call & subsequent messages This routine automatically changes a socket to non-blocking. Clarification of existing specification required. The DLL will be responsible for reposting messages which fail to get posted to the WinSockAPI application. Threads/errno The DLL will support the GetLastError() call to enable retrieval of errno on a per thread basis. getXbyY() Documentation must stress data volatility Data structures will be as per Berkeley There will be asynchronous versions of each getXbyY() call supplied. Asynchronous Every async call returns a descriptor getXbyY() (transaction ID) which can be used to cancel the operation by the new CancelXbyY() routine. FD_??? macros Bit positions are indexes into an array of socket slots Documentation notes Documentation to mention that a sociable application should close all existing sockets & ideally wait for any pending asynchronous calls to complete Documentation to assert that an application should not be exited when re-entrantly called due to a blocking operation. get/sethostent() To be removed. Installation check Need mechanism for checking presence of a WinSockAPI conformant DLL and to get appropriate data on the DLL implementation. Non-Berkeley API SelectWindow() Summary AsyncGetXbyY() CancelGetXbyY() HookBlocking() Blocking loop hooking The way in which the WinSockAPI DLL relinquishes the processor during a blocking operation can be controlled by providing a mechanism for "hooking" the routine used by the DLL. Summary of Outstanding Issues at Revision 1.1 --------------------------------------------- All apparent outstanding technical issues have been folded into Revision 1.2. It now remains to flesh out the specification with the semantics of the routines (Berkeley routines & extensions). Connectothon (Feb 18 1992) was proposed as the next appopriate venue for committee meeting. ------------------------------------------------------------------------- Martin Hall 108 Whispering Pines Drive, Suite 115 JSB Corporation California 95066 martinh@jsbus.com Tel: 408-438-8300 Fax: 408-438-8360