1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
|
/*
FALCON - The Falcon Programming Language.
FILE: socket.cpp
The socket module.
-------------------------------------------------------------------
Author: Giancarlo Niccolai
Begin: 2006-05-09 15:50
-------------------------------------------------------------------
(C) Copyright 2004: the FALCON developers (see list in AUTHORS file)
See LICENSE file for licensing details.
*/
/** \file
The socket module.
*/
#include <falcon/module.h>
#include "socket_ext.h"
#include "socket_sys.h"
#include "socket_st.h"
#include "version.h"
#if WITH_OPENSSL
#include <openssl/ssl.h> // check for OPENSSL_NO_SSL2
#endif // WITH_OPENSSL
/*#
@module feathers.socket Low level IP networking.
@brief Low level TCP/IP networking support.
The socket module provides a low level access to network (TCP/IP) socket wise
functions. UDP and TCP protocol are supported, and the module provides also name
resolution facilities, both performed automatically when calling connect and
bind methods, or manually by calling an appropriate name or address resolution
routine.
The module supports both IPv4 and IPv6 networking; generally, IPv6 is chosen
transparently when an IPv6 address is provided or retrieved by the name
resolution system, if the host system supports it.
The Socket module defines a @a NetError class that is raised on network errors. The
class is derived from core IoError and doesn't add any method or property.
@note The module can be loaded using the command
@code
load socket
@endcode
@beginmodule feathers.socket
*/
FALCON_MODULE_DECL
{
#define FALCON_DECLARE_MODULE self
if ( ! Falcon::Sys::init_system() )
{
return 0;
}
Falcon::Module *self = new Falcon::Module();
self->name( "socket" );
self->language( "en_US" );
self->engineVersion( FALCON_VERSION_NUM );
self->version( VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION );
//====================================
// Message setting
#include "socket_st.h"
//====================================
// Net error code enumeration
/*#
@enum NetErrorCode
@brief Network failure error categories.
This error codes define macro-categories of network errors that
have appened. Details are available by reading the system specific
net-error.
The @a NetError.code property assumes one of this values:
- @b generic: A generic failure prevented the network layer to work
altogether. I.e. it was not possible to initialize
the network layer
- @b resolv: An error happened while trying to resolve a network
address; possibly, the name resolution service was
not available or failed altogether.
- @b create: It was impossible to create the socket.
- @b send: The network had an error while trying to send data.
- @b receive: The network had an error while receiving data from a remote host.
- @b close: An error was detected while closing the socket. Either the socket
could not be closed (i.e. because it was already invalid) or the
close sequence was disrupted by a network failure.
- @b bind: The required address could not be allocated by the calling process.
Either the address is already busy or the bind operation required
privileges not owned by the process.
- @b accept: The network system failed while accepting an incoming connection.
This usually means that the accepting thread has become unavailable.
*/
Falcon::Symbol *c_errcode = self->addClass( "NetErrorCode" );
self->addClassProperty( c_errcode, "generic").setInteger( FALSOCK_ERR_GENERIC );
self->addClassProperty( c_errcode, "resolv").setInteger( FALSOCK_ERR_RESOLV );
self->addClassProperty( c_errcode, "create").setInteger( FALSOCK_ERR_CREATE );
self->addClassProperty( c_errcode, "send").setInteger( FALSOCK_ERR_SEND );
self->addClassProperty( c_errcode, "receive").setInteger( FALSOCK_ERR_RECV );
self->addClassProperty( c_errcode, "close").setInteger( FALSOCK_ERR_CLOSE );
self->addClassProperty( c_errcode, "bind").setInteger( FALSOCK_ERR_BIND );
self->addClassProperty( c_errcode, "accept").setInteger( FALSOCK_ERR_ACCEPT );
//====================================
// Generic functions
self->addExtFunc( "getHostName", Falcon::Ext::falcon_getHostName );
self->addExtFunc( "resolveAddress", Falcon::Ext::resolveAddress )->
addParam("address");
self->addExtFunc( "socketErrorDesc", Falcon::Ext::socketErrorDesc )->
addParam("code");
self->addExtFunc( "haveSSL", Falcon::Ext::falcon_haveSSL );
#if WITH_OPENSSL
#ifndef OPENSSL_NO_SSL2
self->addConstant( "SSLv2", (Falcon::int64) Falcon::Sys::SSLData::SSLv2 );
#endif
self->addConstant( "SSLv3", (Falcon::int64) Falcon::Sys::SSLData::SSLv3 );
self->addConstant( "SSLv23", (Falcon::int64) Falcon::Sys::SSLData::SSLv23 );
self->addConstant( "TLSv1", (Falcon::int64) Falcon::Sys::SSLData::TLSv1 );
self->addConstant( "DTLSv1", (Falcon::int64) Falcon::Sys::SSLData::DTLSv1 );
#endif // WITH_OPENSSL
//====================================
// private class socket.
Falcon::Symbol *c_socket = self->addClass( "Socket", Falcon::Ext::Socket_init, false );
self->addClassMethod( c_socket, "getTimeout", Falcon::Ext::Socket_getTimeout );
self->addClassMethod( c_socket, "setTimeout", Falcon::Ext::Socket_setTimeout ).asSymbol()->
addParam("timeout");
self->addClassMethod( c_socket, "dispose", Falcon::Ext::Socket_dispose );
self->addClassMethod( c_socket, "readAvailable", Falcon::Ext::Socket_readAvailable ).asSymbol()->
addParam("timeout");
self->addClassMethod( c_socket, "writeAvailable", Falcon::Ext::Socket_writeAvailable ).asSymbol()->
addParam("timeout");
self->addClassMethod( c_socket, "getService", Falcon::Ext::Socket_getService );
self->addClassMethod( c_socket, "getHost", Falcon::Ext::Socket_getHost );
self->addClassMethod( c_socket, "getPort", Falcon::Ext::Socket_getPort );
self->addClassProperty( c_socket, "timedOut" );
self->addClassProperty( c_socket, "lastError" );
//====================================
// TCP socket
Falcon::Symbol *tcpsocket = self->addClass( "TCPSocket", Falcon::Ext::TCPSocket_init );
tcpsocket->setWKS( true ); // needed by TCPServer
tcpsocket->getClassDef()->addInheritance( new Falcon::InheritDef( c_socket ) );
self->addClassMethod( tcpsocket, "connect", Falcon::Ext::TCPSocket_connect ).asSymbol()->
addParam("host")->addParam("service");
self->addClassMethod( tcpsocket, "isConnected", Falcon::Ext::TCPSocket_isConnected );
self->addClassMethod( tcpsocket, "send", Falcon::Ext::TCPSocket_send ).asSymbol()->
addParam("buffer")->addParam("size")->addParam("start");
self->addClassMethod( tcpsocket, "recv", Falcon::Ext::TCPSocket_recv ).asSymbol()->
addParam("bufOrSize");
self->addClassMethod( tcpsocket, "close", Falcon::Ext::TCPSocket_close );
self->addClassMethod( tcpsocket, "closeRead", Falcon::Ext::TCPSocket_closeRead );
self->addClassMethod( tcpsocket, "closeWrite", Falcon::Ext::TCPSocket_closeWrite );
#if WITH_OPENSSL
self->addClassMethod( tcpsocket, "sslConfig", Falcon::Ext::TCPSocket_sslConfig );
self->addClassMethod( tcpsocket, "sslClear", Falcon::Ext::TCPSocket_sslClear );
self->addClassMethod( tcpsocket, "sslConnect", Falcon::Ext::TCPSocket_sslConnect );
#endif
//====================================
// UDP socket
Falcon::Symbol *udpsocket = self->addClass( "UDPSocket", Falcon::Ext::UDPSocket_init );
udpsocket->getClassDef()->addInheritance( new Falcon::InheritDef( c_socket ) );
self->addClassMethod( udpsocket, "broadcast", Falcon::Ext::UDPSocket_broadcast );
self->addClassMethod( udpsocket, "sendTo", Falcon::Ext::UDPSocket_sendTo ).asSymbol()->
addParam("host")->addParam("service")->addParam("buffer")->addParam("size")->addParam("start");
self->addClassMethod( udpsocket, "recv", Falcon::Ext::UDPSocket_recv ).asSymbol()->
addParam("bufOrSize");
self->addClassProperty( udpsocket, "remote" );
self->addClassProperty( udpsocket, "remoteService" );
//====================================
// TCP server
Falcon::Symbol *tcpserver = self->addClass( "TCPServer", Falcon::Ext::TCPServer_init );
self->addClassMethod( tcpserver, "dispose", Falcon::Ext::TCPServer_dispose );
self->addClassMethod( tcpserver, "bind", Falcon::Ext::TCPServer_bind ).asSymbol()->
addParam("addrOrService")->addParam("service");
self->addClassMethod( tcpserver, "accept", Falcon::Ext::TCPServer_accept ).asSymbol()->
addParam("timeout");
self->addClassProperty( tcpserver, "lastError" );
//==================================================
// Error class
Falcon::Symbol *error_class = self->addExternalRef( "IoError" ); // it's external
Falcon::Symbol *neterr_cls = self->addClass( "NetError", Falcon::Ext::NetError_init );
neterr_cls->setWKS( true );
neterr_cls->getClassDef()->addInheritance( new Falcon::InheritDef( error_class ) );
return self;
}
/* end of socket.cpp */
/* vim: set ai et sw=3 ts= sts=3: */
|