📄 udpw32.c
字号:
/******************************************************************* * * * This file is a part of the eXtremeDB HA framework * * Copyright (c) 2001-2006 McObject LLC * * All Rights Reserved * * * *******************************************************************//* * ++ * * PROJECT: eXtremeDB(tm) (c) McObject LLC * * SUBSYSTEM: HA support * * MODULE: udpw32.c * * ABSTRACT: Low level OS dependent IPC. * Channel-over-UDP, platform dependent functions * * * VERSION: 1.0 * * HISTORY: * 1.0- 1 SS 19-Feb-2004 Created it was * * -- */#ifdef _WIN32#define INCLUDE_SOCKETS#include "interface.h"#include "stdio.h"#ifdef CFG_UDP_SOCKET_CHANNELextern int2 allocate_index();extern void deallocate_index(int2 index);extern void reallocate_index(int2 index);externMCO_RET _nw_send_message( nw_channel_h chan, uint1 type, const void* buffer, int2 buflen, timer_unit timeout );externMCO_RET _nw_recv_message( nw_channel_h chan, uint1 type, const void* buffer, int2 buflen, PSHORT recvlen, timer_unit timeout );extern uint4 NumBytes;int conn_flag = 0;timer_unit init_time = 0;int commit_initialized = 0;udp_msg_buf_t msgbuf;/***************************************************************************/void nw_attach_buffer( nw_channel_h chan, PVOID buffer, uint2 bufsize)/* * attaches framebuffer to a channel */{ chan->pMsg = (udp_msg_buf_h)buffer; chan->bufsize = (uint2)(bufsize + sizeof(udp_msg_buf_t));}/****************************************************************************** * function init_channel() - initializes the listener channel */static MCO_RET init_channel(nw_channel_h ch) /* pointer to channel descriptor */{ ch->recv_seqn = 0; ch->send_seqn = 0; ch->destaddr = 0; ch->pMsg = (udp_msg_buf_h)&msgbuf; ch->bufsize = sizeof(udp_msg_buf_t); ch->currlen = 0; ch->index = -1; ch->socket = -1; ch->status = 0; ch->event = NULL; ch->event1 = NULL; return MCO_S_OK;}/************************************************************************ * * Description: * * Closes the communication channel * * Parameters: * * IN nw_channel_h ch - pointer to a channel descriptor. * * Return: * * Returns MSO_S_OK if successful or error code (see above). * ************************************************************************/MCO_RET nw_close( nw_channel_h chan){ if(chan->socket != -1) { closesocket(chan->socket); chan->socket = -1; } deallocate_index(chan->index); init_channel(chan); return MCO_S_OK;}/****************************************************************************** * function create_socket() - creates the socket *//************************************************************************** * * Description: * * Creates an overlapped UDP socket. * * IN nw_channel_h ch - pointer to a channel descriptor. * IN uint2 flag - channel flags * * Returns MSO_S_OK if successful or error code (see above). * **************************************************************************/static MCO_RET create_socket( nw_channel_h chan, uint2 flags){ int optval = 1; uint4 mode = 1; if( (chan->socket= WSASocket(PF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_OVERLAPPED)) <0) { return (MCO_RET)(MCO_E_NW_FATAL); } chan->sin.sin_family = AF_INET; // Internet protocol stack chan->sin.sin_addr.s_addr = htonl(chan->destaddr); // destination address chan->sin.sin_port = htons(chan->port); // owner port number setsockopt (chan->socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&optval, sizeof(int) ); /* bind socket with the mentioned parameters */ if ( bind(chan->socket, (LPSOCKADDR)&chan->sin, sizeof(chan->sin)) != 0 ) { nw_close(chan); return (MCO_RET)(MCO_E_NW_ERROR); } if (ioctlsocket(chan->socket, FIONBIO, (PDWORD)&mode) < 0 ) { nw_close(chan); return (MCO_RET)(MCO_E_NW_FATAL); } chan->event = CreateEvent( NULL, 0, 0, NULL); chan->event1 = CreateEvent( NULL, 0, 0, NULL); chan->status = (uint2)(NWST_INITIALIZED | flags); // base channel status = initialized return MCO_S_OK;}/*************************************************************************** * * Description: * * Initializes the network protocol & base channel descriptor. * The base channel is the main channel descriptor used by server for accepting * client's connections requests. The descriptor of base channel MAY contain * extention including common properties of the transport layer. * * Parameters: * * IN nw_channel_h chan - pointer to the base channel descriptor. * * Return: * * Returns MSO_S_OK if successful or error code (see above). * ***************************************************************************/MCO_RET nw_init( nw_channel_h chan){ uint2 wVersionRequested; WSADATA wsaData; int err; chan->index = -2; wVersionRequested = MAKEWORD( 1, 1 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ return (MCO_RET)(MCO_E_NW_NOTSUPP); } if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ WSACleanup( ); return (MCO_RET)(MCO_E_NW_NOTSUPP); }/* * Creation of the thread that implements shared commit. It is necessary * if you need to run several masters sharing the same database in the shared memory segment. */ /* The WinSock DLL is acceptable. Proceed. */ chan->status = NWST_INITIALIZED; // base channel status = initialized return MCO_S_OK;}/************************************************************************ * * Description: * * Sets the listener state of the IO channel. * * Parameters: * * IN nw_channel_h chan - pointer to a channel descriptor. * IN const char * nw_dev - listener channel name * * Return: * * Returns MSO_S_OK if successful or error code (see above). * ************************************************************************/MCO_RET nw_listen( nw_channel_h chan, const char * nw_dev)/* * IN nw_channel_h chan - pointer to a channel descriptor. * IN const char * nw_dev - listener channel name * * Description: * Sets the IO channel to the listener state. * * Returns MSO_S_OK if successful or error code. */{ /* create UDP socket*/ init_channel(chan); chan->port =(int2)atoi(nw_dev); // listener port number chan->destaddr = (uint4)INADDR_ANY; // enable to listen to any host return create_socket(chan,(NWST_LISTEN|NWST_CONNECTED));}/************************************************************************ * * Description: * Waits for the connection of a remote host to the IO channel. * * Parameters: * * IN nw_channel_h chan - pointer to the listener channel. * IN OUT nw_channel_h ioch - pointer to the IO channel waiting for connection. * IN timer_unit timeout - wait-for-connect timeout. * * Return: * * Returns MSO_S_OK if successful or error code (see above). * ************************************************************************/MCO_RET nw_accept( nw_channel_h chan, nw_channel_h ioch, timer_unit timeout ){ int2 len; conn_msg_t msg; MCO_RET rc; timer_unit time = timeout; timer_unit t1, t2; if(timeout != MCO_TM_INFINITE) { t1 = t2 = mco_system_get_current_time(); } init_channel(ioch); chan->recv_seqn = 0; chan->send_seqn = 0; chan->pMsg = (udp_msg_buf_h)&msg; chan->bufsize = sizeof(conn_msg_t); chan->destaddr = 0; if( (rc = _nw_recv_message( chan, // pointer to a channel object FT_CONNECT, // message type &msg.body, // receive buffer sizeof(msg.body), // receive buffer limit &len, // return actual length time) // connect timeout )!= MCO_S_OK ) {ErrRet0: nw_close(chan); return rc; } msg.body.index=(uint2)(ioch->index=allocate_index()); // channel index ioch->port = (uint2)(chan->port+((ioch->index+1)<<1)); msg.body.port = (uint2)(ioch->port); // IO channel port number ioch->destaddr = (uint4)INADDR_ANY; ioch->destport = (uint2)(ioch->port+1); /* create UDP socket*/ if((rc=create_socket(ioch,NWST_CONNECTED)) != MCO_S_OK) // create socket {ErrRet: nw_close(ioch); goto ErrRet0; } ioch->destaddr = chan->inaddr; if(timeout != MCO_TM_INFINITE) { if( ((t2=mco_system_get_current_time())-t1) > time) { rc = (MCO_RET)(MCO_E_NW_TIMEOUT); goto ErrRet; } time -= t2 - t1; t2 = t1; } if( (rc= _nw_send_message( chan, FT_ACCEPT, &msg.body, sizeof(msg.body), time) ) != MCO_S_OK ) { goto ErrRet; } return MCO_S_OK;}/************************************************************************* * * Description: * Connects IO channel to the remote host by it's name. * * Parameters: * * IN nw_channel_h chan - pointer to a channel descriptor * IN const char connect_string - interconnect dependent connection-string * IN timer_unit timeout - connection timeout * * Return: * * Returns MSO_S_OK if successful or error code (see above). * *************************************************************************/MCO_RET nw_connect( nw_channel_h chan, const char* connect_string, timer_unit timeout ){ short len; const char* cc = connect_string; char name[128]; nw_channel_t lch; conn_msg_t msg; MCO_RET rc; timer_unit time = timeout; timer_unit t1, t2; struct hostent *he; if(timeout != MCO_TM_INFINITE) { t1 = t2 = mco_system_get_current_time(); }/* * Find ':' in connect string */ for (;;) { if ( *cc == '\0' ) return (MCO_RET)(MCO_E_NW_INVADDR); if ( *cc == ':' ) break; cc++; } cc++; if ( (cc-connect_string) >= sizeof(name) ) return (MCO_RET)(MCO_E_NW_NOMEM); strncpy(name, connect_string, (int)(cc-connect_string-1)); name[(int)(cc-connect_string-1)] = 0; init_channel(&lch); init_channel(chan); lch.pMsg = (udp_msg_buf_h)&msg; lch.bufsize = sizeof(conn_msg_t); lch.destport = (uint2)atoi(cc); msg.body.port = lch.port = (uint2)(lch.destport+1); msg.body.index = 0;/* * Translate IP address */ if ( (he = gethostbyname(name)) == NULL ) return (MCO_RET)(MCO_E_NW_INVADDR); lch.destaddr = INADDR_ANY; if( (rc=create_socket(&lch,NWST_CONNECTED)) != MCO_S_OK) {ErrRet: nw_close(&lch); return rc; } lch.destaddr = ntohl(*(PULONG)(he->h_addr_list[0])); // destination address if( (rc= _nw_send_message( &lch, FT_CONNECT, &msg.body, sizeof(msg.body), time) ) != MCO_S_OK ) { rc = (MCO_RET)(MCO_E_NW_CONNECT); goto ErrRet; } if(timeout != MCO_TM_INFINITE) { if( ((t2=mco_system_get_current_time())-t1) > time) { rc = (MCO_RET)(MCO_E_NW_TIMEOUT); goto ErrRet; } time -= t2 - t1; t2 = t1; } if( (rc= _nw_recv_message( &lch, FT_ACCEPT, &msg.body, sizeof(msg.body), &len, time) ) != MCO_S_OK ) { rc = (MCO_RET)(MCO_E_NW_CONNECT); goto ErrRet; } chan->destport = msg.body.port; chan->port = (uint2)(msg.body.port+1); chan->index = msg.body.index; chan->destaddr = INADDR_ANY; if( (rc=create_socket(chan,NWST_CONNECTED)) != MCO_S_OK) { nw_close(chan); goto ErrRet; } chan->destaddr = lch.inaddr; nw_close(&lch); return MCO_S_OK;}/* Not implemented. The stubs for the compliance with other platforms. *//*************************************************************************** * * Accept the cancel point connection * * IN nw_channel_h chan - pointer to the listener channel. * IN OUT nw_channel_h ioch - pointer to the IO channel waiting for connection. * IN unsigned long timeout) - wait-for-connect timeout. * * Description: * Waits for the connection of a remote host to the IO channel. * * Returns MSO_S_OK if successful or error code (see above). */MCO_RET nw_accept_cancel_point( nw_channel_h chan, char * port, timer_unit timeout ){ return MCO_S_OK;}/*************************************************************************** * * Connect to cancel point * * IN nw_channel_h chan - pointer to a channel descriptor * IN const char connect_string - interconnect dependent connection-string * IN unsigned long timeout); * * Description: * Connects IO channel to the remote host by it's name.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -