WIP
This commit is contained in:
parent
94ab52cd01
commit
1ffb1ee0d0
|
@ -83,6 +83,7 @@ dialplans/mod_dialplan_xml
|
|||
#endpoints/mod_h323
|
||||
#endpoints/mod_khomp
|
||||
endpoints/mod_rtc
|
||||
endpoints/mod_verto
|
||||
endpoints/mod_loopback
|
||||
#endpoints/mod_opal
|
||||
#endpoints/mod_portaudio
|
||||
|
|
|
@ -1500,6 +1500,7 @@ AC_CONFIG_FILES([Makefile
|
|||
src/mod/endpoints/mod_sofia/Makefile
|
||||
src/mod/endpoints/mod_unicall/Makefile
|
||||
src/mod/endpoints/mod_rtc/Makefile
|
||||
src/mod/endpoints/mod_verto/Makefile
|
||||
src/mod/event_handlers/mod_cdr_csv/Makefile
|
||||
src/mod/event_handlers/mod_cdr_mongodb/Makefile
|
||||
src/mod/event_handlers/mod_cdr_pg_csv/Makefile
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
include $(top_srcdir)/build/modmake.rulesam
|
||||
MODNAME=mod_verto
|
||||
|
||||
mod_LTLIBRARIES = mod_verto.la
|
||||
mod_verto_la_SOURCES = mod_verto.c ws.c mcast/mcast.c
|
||||
mod_verto_la_CFLAGS = -D__EXTENSIONS__ -D_GNU_SOURCE $(AM_CFLAGS)
|
||||
mod_verto_la_CPPFLAGS = -I. -Imcast
|
||||
mod_verto_la_LIBADD = $(switch_builddir)/libfreeswitch.la
|
||||
mod_verto_la_LDFLAGS = -avoid-version -module -no-undefined -shared
|
||||
|
||||
if HAVE_PERL
|
||||
perldir = $(PERL_SITEDIR)
|
||||
perl_LTLIBRARIES = MCAST.la
|
||||
MCAST_la_SOURCES = mcast/mcast_wrap.cpp mcast/perlxsi.c mcast/mcast.c mcast/mcast_cpp.cpp
|
||||
MCAST_la_CFLAGS = $(CC_CFLAGS) $(CFLAGS) $(SWITCH_AM_CFLAGS) $(PERL_CFLAGS)
|
||||
MCAST_la_CXXFLAGS = $(SWITCH_AM_CXXFLAGS) $(CXXFLAGS) -w $(PERL_INC)
|
||||
MCAST_la_CPPFLAGS = -I$(switch_srcdir)/src/mod/endpoints/mod_verto/mcast
|
||||
MCAST_la_LDFLAGS = -avoid-version -module -no-undefined -shared $(PERL_LDFLAGS)
|
||||
|
||||
install-data-local: perlmod-install
|
||||
|
||||
perlmod-install: install-perlLTLIBRARIES
|
||||
install -m 755 MCAST.pm $(PERL_SITEDIR)
|
||||
endif
|
||||
|
||||
mcast/esl_wrap.cpp:
|
||||
cd mcast && swig -module MCAST -shadow -perl5 -c++ -DMULTIPLICITY -I../src/include -o mcast_wrap.cpp ../MCAST.i
|
||||
|
||||
mcast/perlxsi.c:
|
||||
$(PERL) -MExtUtils::Embed -e xsinit -- -o perlxsi.c
|
||||
|
||||
clean-data-local:
|
||||
rm -f *.o *.so *~
|
||||
|
||||
swigclean:
|
||||
rm -f mcast/mcast_wrap.* mcast/MCAST.so mcast/MCAST.pm mcast/perlxsi.*
|
||||
|
||||
reswig: swigclean mcast/mcast_wrap.cpp mcast/perlxsi.c
|
|
@ -0,0 +1,2 @@
|
|||
*.o
|
||||
*.so
|
|
@ -0,0 +1,24 @@
|
|||
%{
|
||||
#include "mcast.h"
|
||||
#include "mcast_cpp.h"
|
||||
%}
|
||||
|
||||
%newobject McastHANDLE::recv;
|
||||
|
||||
%include "mcast_cpp.h"
|
||||
|
||||
%perlcode %{
|
||||
use constant {
|
||||
MCAST_SEND => (1 << 0),
|
||||
MCAST_RECV => (1 << 1),
|
||||
MCAST_TTL_HOST => (1 << 2),
|
||||
MCAST_TTL_SUBNET => (1 << 3),
|
||||
MCAST_TTL_SITE => (1 << 4),
|
||||
MCAST_TTL_REGION => (1 << 5),
|
||||
MCAST_TTL_CONTINENT => (1 << 6),
|
||||
MCAST_TTL_UNIVERSE => (1 << 7)
|
||||
};
|
||||
%}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
# This file was automatically generated by SWIG (http://www.swig.org).
|
||||
# Version 1.3.35
|
||||
#
|
||||
# Don't modify this file, modify the SWIG interface instead.
|
||||
|
||||
package MCAST;
|
||||
require Exporter;
|
||||
require DynaLoader;
|
||||
@ISA = qw(Exporter DynaLoader);
|
||||
package MCASTc;
|
||||
bootstrap MCAST;
|
||||
package MCAST;
|
||||
@EXPORT = qw( );
|
||||
|
||||
# ---------- BASE METHODS -------------
|
||||
|
||||
package MCAST;
|
||||
|
||||
sub TIEHASH {
|
||||
my ($classname,$obj) = @_;
|
||||
return bless $obj, $classname;
|
||||
}
|
||||
|
||||
sub CLEAR { }
|
||||
|
||||
sub FIRSTKEY { }
|
||||
|
||||
sub NEXTKEY { }
|
||||
|
||||
sub FETCH {
|
||||
my ($self,$field) = @_;
|
||||
my $member_func = "swig_${field}_get";
|
||||
$self->$member_func();
|
||||
}
|
||||
|
||||
sub STORE {
|
||||
my ($self,$field,$newval) = @_;
|
||||
my $member_func = "swig_${field}_set";
|
||||
$self->$member_func($newval);
|
||||
}
|
||||
|
||||
sub this {
|
||||
my $ptr = shift;
|
||||
return tied(%$ptr);
|
||||
}
|
||||
|
||||
|
||||
# ------- FUNCTION WRAPPERS --------
|
||||
|
||||
package MCAST;
|
||||
|
||||
|
||||
############# Class : MCAST::McastHandle ##############
|
||||
|
||||
package MCAST::McastHandle;
|
||||
use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
|
||||
@ISA = qw( MCAST );
|
||||
%OWNER = ();
|
||||
%ITERATORS = ();
|
||||
sub new {
|
||||
my $pkg = shift;
|
||||
my $self = MCASTc::new_McastHandle(@_);
|
||||
bless $self, $pkg if defined($self);
|
||||
}
|
||||
|
||||
sub DESTROY {
|
||||
return unless $_[0]->isa('HASH');
|
||||
my $self = tied(%{$_[0]});
|
||||
return unless defined $self;
|
||||
delete $ITERATORS{$self};
|
||||
if (exists $OWNER{$self}) {
|
||||
MCASTc::delete_McastHandle($self);
|
||||
delete $OWNER{$self};
|
||||
}
|
||||
}
|
||||
|
||||
*send = *MCASTc::McastHandle_send;
|
||||
*recv = *MCASTc::McastHandle_recv;
|
||||
*fileno = *MCASTc::McastHandle_fileno;
|
||||
sub DISOWN {
|
||||
my $self = shift;
|
||||
my $ptr = tied(%$self);
|
||||
delete $OWNER{$ptr};
|
||||
}
|
||||
|
||||
sub ACQUIRE {
|
||||
my $self = shift;
|
||||
my $ptr = tied(%$self);
|
||||
$OWNER{$ptr} = 1;
|
||||
}
|
||||
|
||||
|
||||
# ------- VARIABLE STUBS --------
|
||||
|
||||
package MCAST;
|
||||
|
||||
|
||||
use constant {
|
||||
MCAST_SEND => (1 << 0),
|
||||
MCAST_RECV => (1 << 1),
|
||||
MCAST_TTL_HOST => (1 << 2),
|
||||
MCAST_TTL_SUBNET => (1 << 3),
|
||||
MCAST_TTL_SITE => (1 << 4),
|
||||
MCAST_TTL_REGION => (1 << 5),
|
||||
MCAST_TTL_CONTINENT => (1 << 6),
|
||||
MCAST_TTL_UNIVERSE => (1 << 7)
|
||||
};
|
||||
1;
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include "mcast.h"
|
||||
#include <poll.h>
|
||||
|
||||
int mcast_socket_create(const char *host, int16_t port, mcast_handle_t *handle, mcast_flag_t flags)
|
||||
{
|
||||
uint32_t one = 1;
|
||||
|
||||
memset(handle, 0, sizeof(*handle));
|
||||
|
||||
if ((!(flags & MCAST_SEND) && !(flags & MCAST_RECV)) || !(handle->sock = socket(AF_INET, SOCK_DGRAM, 0))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
handle->send_addr.sin_family = AF_INET;
|
||||
handle->send_addr.sin_addr.s_addr = inet_addr(host);
|
||||
handle->send_addr.sin_port = htons(port);
|
||||
|
||||
setsockopt(handle->sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
|
||||
|
||||
|
||||
if ((flags & MCAST_RECV)) {
|
||||
struct ip_mreq mreq;
|
||||
|
||||
handle->recv_addr.sin_family = AF_INET;
|
||||
handle->recv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
handle->recv_addr.sin_port = htons(port);
|
||||
|
||||
mreq.imr_multiaddr.s_addr = inet_addr(host);
|
||||
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
if (setsockopt(handle->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
|
||||
close(handle->sock);
|
||||
handle->sock = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bind(handle->sock, (struct sockaddr *) &handle->recv_addr, sizeof(handle->recv_addr)) < 0) {
|
||||
close(handle->sock);
|
||||
handle->sock = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
handle->ttl = 1;
|
||||
|
||||
if ((flags & MCAST_TTL_HOST)) {
|
||||
handle->ttl = 0;
|
||||
}
|
||||
|
||||
if ((flags & MCAST_TTL_SUBNET)) {
|
||||
handle->ttl = 1;
|
||||
}
|
||||
|
||||
if ((flags & MCAST_TTL_SITE)) {
|
||||
handle->ttl = 32;
|
||||
}
|
||||
|
||||
if ((flags & MCAST_TTL_REGION)) {
|
||||
handle->ttl = 64;
|
||||
}
|
||||
|
||||
if ((flags & MCAST_TTL_CONTINENT)) {
|
||||
handle->ttl = 128;
|
||||
}
|
||||
|
||||
if ((flags & MCAST_TTL_UNIVERSE)) {
|
||||
handle->ttl = 255;
|
||||
}
|
||||
|
||||
setsockopt(handle->sock, IPPROTO_IP, IP_MULTICAST_TTL, &handle->ttl, sizeof(handle->ttl));
|
||||
|
||||
handle->ready = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void mcast_socket_close(mcast_handle_t *handle)
|
||||
{
|
||||
if (handle->sock > -1) {
|
||||
close(handle->sock);
|
||||
handle->sock = -1;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t mcast_socket_send(mcast_handle_t *handle, void *data, size_t datalen)
|
||||
{
|
||||
if (handle->sock <= -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (data == NULL || datalen == 0) {
|
||||
data = handle->buffer;
|
||||
datalen = sizeof(handle->buffer);
|
||||
}
|
||||
|
||||
return sendto(handle->sock, data, datalen, 0, (struct sockaddr *) &handle->send_addr, sizeof(handle->send_addr));
|
||||
}
|
||||
|
||||
ssize_t mcast_socket_recv(mcast_handle_t *handle, void *data, size_t datalen, int ms)
|
||||
{
|
||||
socklen_t addrlen = sizeof(handle->recv_addr);
|
||||
int r;
|
||||
|
||||
if (data == NULL || datalen == 0) {
|
||||
data = handle->buffer;
|
||||
datalen = sizeof(handle->buffer);
|
||||
}
|
||||
|
||||
if (ms > 0) {
|
||||
struct pollfd pfds[1];
|
||||
|
||||
pfds[0].fd = handle->sock;
|
||||
pfds[0].events = POLLIN|POLLERR;
|
||||
|
||||
if ((r = poll(pfds, 1, ms)) <= 0) {
|
||||
return r;
|
||||
}
|
||||
|
||||
if (pfds[0].revents & POLLERR) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return recvfrom(handle->sock, data, datalen, 0, (struct sockaddr *) &handle->recv_addr, &addrlen);
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __MCAST_H
|
||||
#define __MCAST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* defined(__cplusplus) */
|
||||
#if EMACS_WORKS
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
typedef struct {
|
||||
int sock;
|
||||
unsigned char ttl;
|
||||
struct sockaddr_in send_addr;
|
||||
struct sockaddr_in recv_addr;
|
||||
unsigned char buffer[65536];
|
||||
int ready;
|
||||
} mcast_handle_t;
|
||||
|
||||
typedef enum {
|
||||
MCAST_SEND = (1 << 0),
|
||||
MCAST_RECV = (1 << 1),
|
||||
MCAST_TTL_HOST = (1 << 2),
|
||||
MCAST_TTL_SUBNET = (1 << 3),
|
||||
MCAST_TTL_SITE = (1 << 4),
|
||||
MCAST_TTL_REGION = (1 << 5),
|
||||
MCAST_TTL_CONTINENT = (1 << 6),
|
||||
MCAST_TTL_UNIVERSE = (1 << 7)
|
||||
} mcast_flag_t;
|
||||
|
||||
int mcast_socket_create(const char *host, int16_t port, mcast_handle_t *handle, mcast_flag_t flags);
|
||||
void mcast_socket_close(mcast_handle_t *handle);
|
||||
ssize_t mcast_socket_send(mcast_handle_t *handle, void *data, size_t datalen);
|
||||
ssize_t mcast_socket_recv(mcast_handle_t *handle, void *data, size_t datalen, int ms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "mcast.h"
|
||||
#include "mcast_cpp.h"
|
||||
#include <string.h>
|
||||
#include <poll.h>
|
||||
|
||||
McastHandle::McastHandle(const char *host, int port, int flags)
|
||||
{
|
||||
mcast_socket_create(host, port, &handle, (mcast_flag_t) flags);
|
||||
}
|
||||
|
||||
McastHandle::~McastHandle()
|
||||
{
|
||||
mcast_socket_close(&handle);
|
||||
}
|
||||
|
||||
int McastHandle::send(const char *data)
|
||||
{
|
||||
return (int) mcast_socket_send(&handle, (void *)data, strlen(data) + 1);
|
||||
}
|
||||
|
||||
char *McastHandle::recv(int ms)
|
||||
{
|
||||
int r;
|
||||
|
||||
if ((r = mcast_socket_recv(&handle, NULL, 0, ms)) > 0) {
|
||||
*((char *)handle.buffer + r) = '\0';
|
||||
return (char *) handle.buffer;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int McastHandle::fileno(void)
|
||||
{
|
||||
return handle.sock;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __MCAST_CPP_H
|
||||
#define __MCAST_CPP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* defined(__cplusplus) */
|
||||
#if EMACS_WORKS
|
||||
}
|
||||
#endif
|
||||
|
||||
class McastHandle {
|
||||
private:
|
||||
mcast_handle_t handle;
|
||||
public:
|
||||
McastHandle(const char *host, int port, int flags);
|
||||
virtual ~McastHandle();
|
||||
int send(const char *data);
|
||||
char *recv(int ms = 0);
|
||||
int fileno(void);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,16 @@
|
|||
#include <EXTERN.h>
|
||||
#include <perl.h>
|
||||
|
||||
EXTERN_C void xs_init (pTHX);
|
||||
|
||||
EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
|
||||
|
||||
EXTERN_C void
|
||||
xs_init(pTHX)
|
||||
{
|
||||
char *file = __FILE__;
|
||||
dXSUB_SYS;
|
||||
|
||||
/* DynaLoader is a special case */
|
||||
newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "mcast.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
mcast_handle_t handle;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("WTF\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
mcast_socket_create("231.3.3.7", 1337, &handle, MCAST_SEND | MCAST_RECV | MCAST_TTL_HOST);
|
||||
perror("create");
|
||||
|
||||
if (!strcmp(argv[1], "send")) {
|
||||
mcast_socket_send(&handle, argv[2], strlen(argv[2]));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
int r = mcast_socket_recv(&handle, NULL, 0);
|
||||
printf("RECV %d [%s]\n", r, (char *)handle.buffer);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
use MCAST;
|
||||
|
||||
my $s = new MCAST::McastHandle("231.3.3.7", 1337, MCAST_SEND | MCAST_RECV | MCAST_TTL_HOST);
|
||||
|
||||
my $action = shift;
|
||||
|
||||
if ($action eq "send") {
|
||||
$s->send("W00t from Perl " . shift);
|
||||
exit;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
my $foo = $s->recv(100);
|
||||
if ($foo) {
|
||||
print "RECV [$foo]\n";
|
||||
} else {
|
||||
print "PING\n";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
use MCAST;
|
||||
|
||||
|
||||
|
||||
my $action = shift;
|
||||
|
||||
if ($action eq "send") {
|
||||
my $s = new MCAST::McastHandle("224.1.1.1", 1337, MCAST::MCAST_SEND | MCAST::MCAST_TTL_HOST);
|
||||
$s->send(shift);
|
||||
print "Sending message";
|
||||
exit;
|
||||
}
|
||||
|
||||
my $s = new MCAST::McastHandle("224.1.1.1", 1338, MCAST::MCAST_RECV | MCAST::MCAST_TTL_HOST);
|
||||
|
||||
for(;;) {
|
||||
my $foo = $s->recv();
|
||||
if ($foo) {
|
||||
print "RECV [$foo]\n";
|
||||
} else {
|
||||
print "PING\n";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,287 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="mod_verto"
|
||||
ProjectGUID="{11C9BC3D-45E9-46E3-BE84-B8CEE4685E39}"
|
||||
RootNamespace="mod_verto"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\..\..\..\w32\module_debug.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\..\..\..\w32\module_debug.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(SolutionDir)$(PlatformName)\$(ConfigurationName)/mod/$(ProjectName).dll"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\..\..\..\w32\module_release.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\..\..\..\w32\module_release.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(SolutionDir)$(PlatformName)\$(ConfigurationName)/mod/$(ProjectName).dll"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath=".\mod_verto.c"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
|
@ -0,0 +1,131 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>mod_verto</ProjectName>
|
||||
<ProjectGuid>{11C9BC3D-45E9-46E3-BE84-B8CEE4685E39}</ProjectGuid>
|
||||
<RootNamespace>mod_verto</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_release.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_debug.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_release.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_debug.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="mod_verto.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\w32\Library\FreeSwitchCore.2010.vcxproj">
|
||||
<Project>{202d7a4e-760d-4d0e-afa1-d7459ced30ff}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,135 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>mod_verto</ProjectName>
|
||||
<ProjectGuid>{11C9BC3D-45E9-46E3-BE84-B8CEE4685E39}</ProjectGuid>
|
||||
<RootNamespace>mod_verto</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_release.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_debug.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_release.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_debug.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="mod_verto.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\w32\Library\FreeSwitchCore.2012.vcxproj">
|
||||
<Project>{202d7a4e-760d-4d0e-afa1-d7459ced30ff}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* 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 Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* mod_html.h -- HTML 5 interface
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MOD_VERTO_H
|
||||
#define MOD_VERTO_H
|
||||
#include <switch.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/wait.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <poll.h>
|
||||
#include <stdarg.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <sys/un.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <netdb.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include "mcast.h"
|
||||
|
||||
#define MAXPENDING 10000
|
||||
#define STACK_SIZE 80 * 1024
|
||||
|
||||
#define VERTO_CHAT_PROTO "verto"
|
||||
|
||||
#define copy_string(x,y,z) strncpy(x, y, z - 1)
|
||||
#define set_string(x,y) strncpy(x, y, sizeof(x)-1)
|
||||
|
||||
#define CODE_INVALID -32600
|
||||
#define CODE_AUTH_REQUIRED -32000
|
||||
#define CODE_AUTH_FAILED -32001
|
||||
#define CODE_SESSION_ERROR -32002
|
||||
|
||||
|
||||
typedef enum {
|
||||
PTYPE_CLIENT = (1 << 0),
|
||||
PTYPE_CLIENT_SSL = (1 << 1)
|
||||
} jsock_type_t;
|
||||
|
||||
typedef enum {
|
||||
JPFLAG_INIT = (1 << 0),
|
||||
JPFLAG_AUTHED = (1 << 1),
|
||||
JPFLAG_CHECK_ATTACH = (1 << 2)
|
||||
} jpflag_t;
|
||||
|
||||
struct verto_profile_s;
|
||||
|
||||
struct jsock_s {
|
||||
int client_socket;
|
||||
switch_memory_pool_t *pool;
|
||||
switch_thread_t *thread;
|
||||
wsh_t ws;
|
||||
unsigned char buf[65535];
|
||||
char *name;
|
||||
jsock_type_t ptype;
|
||||
struct sockaddr_in local_addr;
|
||||
struct sockaddr_in remote_addr;
|
||||
struct sockaddr_in send_addr;
|
||||
struct ucred credentials;
|
||||
struct passwd pw;
|
||||
|
||||
int drop;
|
||||
int local_sock;
|
||||
SSL *ssl;
|
||||
|
||||
jpflag_t flags;
|
||||
|
||||
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
|
||||
switch_event_t *allowed_methods;
|
||||
switch_event_t *allowed_jsapi;
|
||||
switch_event_t *allowed_fsapi;
|
||||
switch_event_t *allowed_event_channels;
|
||||
|
||||
|
||||
char *id;
|
||||
char *domain;
|
||||
char *uid;
|
||||
char *dialplan;
|
||||
char *context;
|
||||
|
||||
struct verto_profile_s *profile;
|
||||
switch_thread_rwlock_t *rwlock;
|
||||
|
||||
switch_mutex_t *write_mutex;
|
||||
|
||||
switch_event_t *params;
|
||||
switch_event_t *vars;
|
||||
|
||||
struct jsock_s *next;
|
||||
};
|
||||
|
||||
typedef struct jsock_s jsock_t;
|
||||
|
||||
#define MAX_BIND 25
|
||||
#define MAX_RTPIP 25
|
||||
|
||||
struct ips {
|
||||
char local_ip[256];
|
||||
in_addr_t local_ip_addr;
|
||||
int local_port;
|
||||
int secure;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
TFLAG_SENT_MEDIA = (1 << 0),
|
||||
TFLAG_ATTACH_REQ = (1 << 1)
|
||||
} tflag_t;
|
||||
|
||||
typedef struct verto_pvt_s {
|
||||
char *jsock_uuid;
|
||||
char *call_id;
|
||||
char *r_sdp;
|
||||
tflag_t flags;
|
||||
switch_core_session_t *session;
|
||||
switch_channel_t *channel;
|
||||
switch_media_handle_t *smh;
|
||||
switch_core_media_params_t *mparams;
|
||||
switch_call_cause_t remote_hangup_cause;
|
||||
time_t detach_time;
|
||||
struct verto_pvt_s *next;
|
||||
} verto_pvt_t;
|
||||
|
||||
struct verto_profile_s {
|
||||
char *name;
|
||||
switch_mutex_t *mutex;
|
||||
switch_memory_pool_t *pool;
|
||||
switch_thread_rwlock_t *rwlock;
|
||||
|
||||
struct ips ip[MAX_BIND];
|
||||
int i;
|
||||
|
||||
const SSL_METHOD *ssl_method;
|
||||
SSL_CTX *ssl_ctx;
|
||||
char cert[512];
|
||||
char key[512];
|
||||
char chain[512];
|
||||
|
||||
jsock_t *jsock_head;
|
||||
int jsock_count;
|
||||
int server_socket[MAX_BIND];
|
||||
int running;
|
||||
|
||||
int ssl_ready;
|
||||
int ready;
|
||||
int debug;
|
||||
|
||||
int in_thread;
|
||||
|
||||
char *userauth;
|
||||
char *root_passwd;
|
||||
|
||||
char *context;
|
||||
char *dialplan;
|
||||
|
||||
char *mcast_ip;
|
||||
switch_port_t mcast_port;
|
||||
|
||||
mcast_handle_t mcast_sub;
|
||||
mcast_handle_t mcast_pub;
|
||||
|
||||
char *extrtpip;
|
||||
|
||||
char *rtpip[MAX_RTPIP];
|
||||
int rtpip_index;
|
||||
int rtpip_cur;
|
||||
|
||||
char *cand_acl[SWITCH_MAX_CAND_ACL];
|
||||
uint32_t cand_acl_count;
|
||||
|
||||
char *inbound_codec_string;
|
||||
char *outbound_codec_string;
|
||||
|
||||
char *timer_name;
|
||||
char *local_network;
|
||||
|
||||
|
||||
|
||||
struct verto_profile_s *next;
|
||||
};
|
||||
|
||||
typedef struct verto_profile_s verto_profile_t;
|
||||
|
||||
struct globals_s {
|
||||
switch_mutex_t *mutex;
|
||||
switch_memory_pool_t *pool;
|
||||
|
||||
int profile_count;
|
||||
verto_profile_t *profile_head;
|
||||
int sig;
|
||||
int running;
|
||||
|
||||
switch_hash_t *method_hash;
|
||||
switch_mutex_t *method_mutex;
|
||||
|
||||
switch_hash_t *event_channel_hash;
|
||||
switch_thread_rwlock_t *event_channel_rwlock;
|
||||
|
||||
int debug;
|
||||
int ready;
|
||||
int profile_threads;
|
||||
int enable_presence;
|
||||
|
||||
switch_hash_t *jsock_hash;
|
||||
switch_mutex_t *jsock_mutex;
|
||||
|
||||
verto_pvt_t *tech_head;
|
||||
switch_thread_rwlock_t *tech_rwlock;
|
||||
|
||||
switch_thread_cond_t *detach_cond;
|
||||
switch_mutex_t *detach_mutex;
|
||||
switch_mutex_t *detach2_mutex;
|
||||
|
||||
uint32_t detached;
|
||||
uint32_t detach_timeout;
|
||||
|
||||
switch_event_channel_id_t event_channel_id;
|
||||
};
|
||||
|
||||
|
||||
extern struct globals_s globals;
|
||||
|
||||
typedef switch_bool_t (*jrpc_func_t)(const char *method, cJSON *params, jsock_t *jsock, cJSON **response);
|
||||
|
||||
|
||||
void set_log_path(const char *path);
|
||||
|
||||
|
||||
/** @} */
|
||||
#endif
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
|
@ -0,0 +1,879 @@
|
|||
#include "ws.h"
|
||||
#include <pthread.h>
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#define ms_sleep(x) usleep( x * 1000);
|
||||
#else
|
||||
#define ms_sleep(x) Sleep( x );
|
||||
#endif
|
||||
|
||||
#define WS_BLOCK 1
|
||||
#define WS_NOBLOCK 0
|
||||
|
||||
#define SHA1_HASH_SIZE 20
|
||||
struct ws_globals_s ws_globals;
|
||||
|
||||
#ifndef WSS_STANDALONE
|
||||
|
||||
void init_ssl(void)
|
||||
{
|
||||
SSL_library_init();
|
||||
}
|
||||
void deinit_ssl(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
static unsigned long pthreads_thread_id(void);
|
||||
static void pthreads_locking_callback(int mode, int type, const char *file, int line);
|
||||
|
||||
static pthread_mutex_t *lock_cs;
|
||||
static long *lock_count;
|
||||
|
||||
|
||||
|
||||
static void thread_setup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
|
||||
lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
|
||||
|
||||
for (i = 0; i < CRYPTO_num_locks(); i++) {
|
||||
lock_count[i] = 0;
|
||||
pthread_mutex_init(&(lock_cs[i]), NULL);
|
||||
}
|
||||
|
||||
CRYPTO_set_id_callback(pthreads_thread_id);
|
||||
CRYPTO_set_locking_callback(pthreads_locking_callback);
|
||||
}
|
||||
|
||||
static void thread_cleanup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
|
||||
for (i=0; i<CRYPTO_num_locks(); i++) {
|
||||
pthread_mutex_destroy(&(lock_cs[i]));
|
||||
}
|
||||
OPENSSL_free(lock_cs);
|
||||
OPENSSL_free(lock_count);
|
||||
|
||||
}
|
||||
|
||||
static void pthreads_locking_callback(int mode, int type, const char *file, int line)
|
||||
{
|
||||
|
||||
if (mode & CRYPTO_LOCK) {
|
||||
pthread_mutex_lock(&(lock_cs[type]));
|
||||
lock_count[type]++;
|
||||
} else {
|
||||
pthread_mutex_unlock(&(lock_cs[type]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static unsigned long pthreads_thread_id(void)
|
||||
{
|
||||
return (unsigned long) pthread_self();
|
||||
}
|
||||
|
||||
|
||||
void init_ssl(void) {
|
||||
SSL_library_init();
|
||||
|
||||
|
||||
OpenSSL_add_all_algorithms(); /* load & register cryptos */
|
||||
SSL_load_error_strings(); /* load all error messages */
|
||||
ws_globals.ssl_method = TLSv1_server_method(); /* create server instance */
|
||||
ws_globals.ssl_ctx = SSL_CTX_new(ws_globals.ssl_method); /* create context */
|
||||
assert(ws_globals.ssl_ctx);
|
||||
|
||||
/* set the local certificate from CertFile */
|
||||
SSL_CTX_use_certificate_file(ws_globals.ssl_ctx, ws_globals.cert, SSL_FILETYPE_PEM);
|
||||
/* set the private key from KeyFile */
|
||||
SSL_CTX_use_PrivateKey_file(ws_globals.ssl_ctx, ws_globals.key, SSL_FILETYPE_PEM);
|
||||
/* verify private key */
|
||||
if ( !SSL_CTX_check_private_key(ws_globals.ssl_ctx) ) {
|
||||
abort();
|
||||
}
|
||||
|
||||
SSL_CTX_set_cipher_list(ws_globals.ssl_ctx, "HIGH:!DSS:!aNULL@STRENGTH");
|
||||
|
||||
thread_setup();
|
||||
}
|
||||
|
||||
|
||||
void deinit_ssl(void) {
|
||||
thread_cleanup();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static const char c64[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
|
||||
static int cheezy_get_var(char *data, char *name, char *buf, size_t buflen)
|
||||
{
|
||||
char *p=data;
|
||||
|
||||
/* the old way didnt make sure that variable values were used for the name hunt
|
||||
* and didnt ensure that only a full match of the variable name was used
|
||||
*/
|
||||
|
||||
do {
|
||||
if(!strncmp(p,name,strlen(name)) && *(p+strlen(name))==':') break;
|
||||
} while((p = (strstr(p,"\n")+1))!=(char *)1);
|
||||
|
||||
|
||||
if (p != (char *)1 && *p!='\0') {
|
||||
char *v, *e = 0;
|
||||
|
||||
v = strchr(p, ':');
|
||||
if (v) {
|
||||
v++;
|
||||
while(v && *v == ' ') {
|
||||
v++;
|
||||
}
|
||||
if (v) {
|
||||
e = strchr(v, '\r');
|
||||
if (!e) {
|
||||
e = strchr(v, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
if (v && e) {
|
||||
int cplen;
|
||||
size_t len = e - v;
|
||||
|
||||
if (len > buflen - 1) {
|
||||
cplen = buflen -1;
|
||||
} else {
|
||||
cplen = len;
|
||||
}
|
||||
|
||||
strncpy(buf, v, cplen);
|
||||
*(buf+cplen) = '\0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int b64encode(unsigned char *in, size_t ilen, unsigned char *out, size_t olen)
|
||||
{
|
||||
int y=0,bytes=0;
|
||||
size_t x=0;
|
||||
unsigned int b=0,l=0;
|
||||
|
||||
if(olen) {
|
||||
}
|
||||
|
||||
for(x=0;x<ilen;x++) {
|
||||
b = (b<<8) + in[x];
|
||||
l += 8;
|
||||
while (l >= 6) {
|
||||
out[bytes++] = c64[(b>>(l-=6))%64];
|
||||
if(++y!=72) {
|
||||
continue;
|
||||
}
|
||||
//out[bytes++] = '\n';
|
||||
y=0;
|
||||
}
|
||||
}
|
||||
|
||||
if (l > 0) {
|
||||
out[bytes++] = c64[((b%16)<<(6-l))%64];
|
||||
}
|
||||
if (l != 0) while (l < 6) {
|
||||
out[bytes++] = '=', l += 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef NO_OPENSSL
|
||||
static void sha1_digest(char *digest, unsigned char *in)
|
||||
{
|
||||
SHA1Context sha;
|
||||
char *p;
|
||||
int x;
|
||||
|
||||
|
||||
SHA1Init(&sha);
|
||||
SHA1Update(&sha, in, strlen(in));
|
||||
SHA1Final(&sha, digest);
|
||||
}
|
||||
#else
|
||||
|
||||
static void sha1_digest(unsigned char *digest, char *in)
|
||||
{
|
||||
SHA_CTX sha;
|
||||
|
||||
SHA1_Init(&sha);
|
||||
SHA1_Update(&sha, in, strlen(in));
|
||||
SHA1_Final(digest, &sha);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int ws_handshake(wsh_t *wsh)
|
||||
{
|
||||
char key[256] = "";
|
||||
char version[5] = "";
|
||||
char proto[256] = "";
|
||||
char proto_buf[384] = "";
|
||||
char uri[256] = "";
|
||||
char input[256] = "";
|
||||
unsigned char output[SHA1_HASH_SIZE] = "";
|
||||
char b64[256] = "";
|
||||
char respond[512] = "";
|
||||
ssize_t bytes;
|
||||
char *p, *e = 0;
|
||||
|
||||
if (wsh->sock == ws_sock_invalid) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
while((bytes = ws_raw_read(wsh, wsh->buffer + wsh->datalen, wsh->buflen - wsh->datalen, WS_BLOCK)) > 0) {
|
||||
wsh->datalen += bytes;
|
||||
if (strstr(wsh->buffer, "\r\n\r\n") || strstr(wsh->buffer, "\n\n")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bytes > sizeof(wsh->buffer) -1) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
*(wsh->buffer+bytes) = '\0';
|
||||
|
||||
if (strncasecmp(wsh->buffer, "GET ", 4)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
p = wsh->buffer + 4;
|
||||
|
||||
e = strchr(p, ' ');
|
||||
if (!e) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
strncpy(uri, p, e-p);
|
||||
|
||||
cheezy_get_var(wsh->buffer, "Sec-WebSocket-Key", key, sizeof(key));
|
||||
cheezy_get_var(wsh->buffer, "Sec-WebSocket-Version", version, sizeof(version));
|
||||
cheezy_get_var(wsh->buffer, "Sec-WebSocket-Protocol", proto, sizeof(proto));
|
||||
|
||||
if (!*key) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
snprintf(input, sizeof(input), "%s%s", key, WEBSOCKET_GUID);
|
||||
sha1_digest(output, input);
|
||||
b64encode((unsigned char *)output, SHA1_HASH_SIZE, (unsigned char *)b64, sizeof(b64));
|
||||
|
||||
if (*proto) {
|
||||
snprintf(proto_buf, sizeof(proto_buf), "Sec-WebSocket-Protocol: %s\r\n", proto);
|
||||
}
|
||||
|
||||
snprintf(respond, sizeof(respond),
|
||||
"HTTP/1.1 101 Switching Protocols\r\n"
|
||||
"Upgrade: websocket\r\n"
|
||||
"Connection: Upgrade\r\n"
|
||||
"Sec-WebSocket-Accept: %s\r\n"
|
||||
"%s\r\n",
|
||||
b64,
|
||||
proto_buf);
|
||||
|
||||
|
||||
ws_raw_write(wsh, respond, strlen(respond));
|
||||
wsh->handshake = 1;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
|
||||
snprintf(respond, sizeof(respond), "HTTP/1.1 400 Bad Request\r\n"
|
||||
"Sec-WebSocket-Version: 13\r\n\r\n");
|
||||
|
||||
//printf("ERR:\n%s\n", respond);
|
||||
|
||||
|
||||
ws_raw_write(wsh, respond, strlen(respond));
|
||||
|
||||
ws_close(wsh, WS_NONE);
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes, int block)
|
||||
{
|
||||
ssize_t r;
|
||||
int err = 0;
|
||||
|
||||
if (wsh->ssl) {
|
||||
do {
|
||||
r = SSL_read(wsh->ssl, data, bytes);
|
||||
|
||||
ms_sleep(10);
|
||||
|
||||
if (r == -1) {
|
||||
err = SSL_get_error(wsh->ssl, r);
|
||||
|
||||
if (!block && err == SSL_ERROR_WANT_READ) {
|
||||
r = -2;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
} while (r == -1 && err == SSL_ERROR_WANT_READ && wsh->x < 100);
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
do {
|
||||
r = recv(wsh->sock, data, bytes, 0);
|
||||
ms_sleep(10);
|
||||
} while (r == -1 && xp_is_blocking(xp_errno()) && wsh->x < 100);
|
||||
|
||||
if (wsh->x >= 100) {
|
||||
r = -1;
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
if (r > 0) {
|
||||
*((char *)data + r) = '\0';
|
||||
}
|
||||
|
||||
if (r >= 0) {
|
||||
wsh->x = 0;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes)
|
||||
{
|
||||
size_t r;
|
||||
|
||||
if (wsh->ssl) {
|
||||
do {
|
||||
r = SSL_write(wsh->ssl, data, bytes);
|
||||
} while (r == -1 && SSL_get_error(wsh->ssl, r) == SSL_ERROR_WANT_WRITE);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
do {
|
||||
r = send(wsh->sock, data, bytes, 0);
|
||||
} while (r == -1 && xp_is_blocking(xp_errno()));
|
||||
|
||||
//if (r<0) {
|
||||
//printf("wRITE FAIL: %s\n", strerror(errno));
|
||||
//}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
static int setup_socket(ws_socket_t sock)
|
||||
{
|
||||
unsigned long v = 1;
|
||||
|
||||
if (ioctlsocket(sock, FIONBIO, &v) == SOCKET_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int restore_socket(ws_socket_t sock)
|
||||
{
|
||||
unsigned long v = 0;
|
||||
|
||||
if (ioctlsocket(sock, FIONBIO, &v) == SOCKET_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int setup_socket(ws_socket_t sock)
|
||||
{
|
||||
int flags = fcntl(sock, F_GETFL, 0);
|
||||
return fcntl(sock, F_SETFL, flags | O_NONBLOCK);
|
||||
}
|
||||
|
||||
static int restore_socket(ws_socket_t sock)
|
||||
{
|
||||
int flags = fcntl(sock, F_GETFL, 0);
|
||||
|
||||
flags &= ~O_NONBLOCK;
|
||||
|
||||
return fcntl(sock, F_SETFL, flags);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static int establish_logical_layer(wsh_t *wsh)
|
||||
{
|
||||
|
||||
if (!wsh->sanity) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (wsh->logical_established) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (wsh->secure && !wsh->secure_established) {
|
||||
int code;
|
||||
|
||||
if (!wsh->ssl) {
|
||||
wsh->ssl = SSL_new(wsh->ssl_ctx);
|
||||
assert(wsh->ssl);
|
||||
|
||||
SSL_set_fd(wsh->ssl, wsh->sock);
|
||||
}
|
||||
|
||||
do {
|
||||
code = SSL_accept(wsh->ssl);
|
||||
|
||||
if (code == 1) {
|
||||
wsh->secure_established = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (code == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (code < 0) {
|
||||
if (code == -1 && SSL_get_error(wsh->ssl, code) != SSL_ERROR_WANT_READ) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (wsh->block) {
|
||||
ms_sleep(10);
|
||||
} else {
|
||||
ms_sleep(1);
|
||||
}
|
||||
|
||||
wsh->sanity--;
|
||||
|
||||
if (!wsh->block) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
} while (wsh->sanity > 0);
|
||||
|
||||
if (!wsh->sanity) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
while (!wsh->down && !wsh->handshake) {
|
||||
int r = ws_handshake(wsh);
|
||||
|
||||
if (r < 0) {
|
||||
wsh->down = 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!wsh->handshake && !wsh->block) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
wsh->logical_established = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ws_init(wsh_t *wsh, ws_socket_t sock, SSL_CTX *ssl_ctx, int close_sock, int block)
|
||||
{
|
||||
memset(wsh, 0, sizeof(*wsh));
|
||||
|
||||
wsh->sock = sock;
|
||||
wsh->block = block;
|
||||
wsh->sanity = 5000;
|
||||
wsh->ssl_ctx = ssl_ctx;
|
||||
|
||||
if (!ssl_ctx) {
|
||||
ssl_ctx = ws_globals.ssl_ctx;
|
||||
}
|
||||
|
||||
if (close_sock) {
|
||||
wsh->close_sock = 1;
|
||||
}
|
||||
|
||||
wsh->buflen = sizeof(wsh->buffer);
|
||||
wsh->secure = ssl_ctx ? 1 : 0;
|
||||
|
||||
setup_socket(sock);
|
||||
|
||||
if (establish_logical_layer(wsh) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (wsh->down) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ws_destroy(wsh_t *wsh)
|
||||
{
|
||||
|
||||
if (!wsh) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wsh->down) {
|
||||
ws_close(wsh, WS_NONE);
|
||||
}
|
||||
|
||||
if (wsh->down > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
wsh->down = 2;
|
||||
|
||||
if (wsh->ssl) {
|
||||
int code;
|
||||
do {
|
||||
code = SSL_shutdown(wsh->ssl);
|
||||
} while (code == -1 && SSL_get_error(wsh->ssl, code) == SSL_ERROR_WANT_READ);
|
||||
|
||||
SSL_free(wsh->ssl);
|
||||
wsh->ssl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t ws_close(wsh_t *wsh, int16_t reason)
|
||||
{
|
||||
|
||||
if (wsh->down) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
wsh->down = 1;
|
||||
|
||||
if (reason && wsh->sock != ws_sock_invalid) {
|
||||
uint16_t *u16;
|
||||
uint8_t fr[4] = {WSOC_CLOSE | 0x80, 2, 0};
|
||||
|
||||
u16 = (uint16_t *) &fr[2];
|
||||
*u16 = htons((int16_t)reason);
|
||||
ws_raw_write(wsh, fr, 4);
|
||||
}
|
||||
|
||||
restore_socket(wsh->sock);
|
||||
|
||||
if (wsh->close_sock && wsh->sock != ws_sock_invalid) {
|
||||
close(wsh->sock);
|
||||
}
|
||||
|
||||
wsh->sock = ws_sock_invalid;
|
||||
|
||||
return reason * -1;
|
||||
|
||||
}
|
||||
|
||||
ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data)
|
||||
{
|
||||
|
||||
ssize_t need = 2;
|
||||
char *maskp;
|
||||
int ll = 0;
|
||||
|
||||
again:
|
||||
need = 2;
|
||||
maskp = NULL;
|
||||
*data = NULL;
|
||||
|
||||
ll = establish_logical_layer(wsh);
|
||||
|
||||
if (ll < 0) {
|
||||
return ll;
|
||||
}
|
||||
|
||||
if (wsh->down) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!wsh->handshake) {
|
||||
return ws_close(wsh, WS_PROTO_ERR);
|
||||
}
|
||||
|
||||
if ((wsh->datalen = ws_raw_read(wsh, wsh->buffer, 9, wsh->block)) < 0) {
|
||||
if (wsh->datalen == -2) {
|
||||
return -2;
|
||||
}
|
||||
return ws_close(wsh, WS_PROTO_ERR);
|
||||
}
|
||||
|
||||
if (wsh->datalen < need) {
|
||||
if ((wsh->datalen += ws_raw_read(wsh, wsh->buffer + wsh->datalen, 9 - wsh->datalen, WS_BLOCK)) < need) {
|
||||
/* too small - protocol err */
|
||||
return ws_close(wsh, WS_PROTO_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
*oc = *wsh->buffer & 0xf;
|
||||
|
||||
switch(*oc) {
|
||||
case WSOC_CLOSE:
|
||||
{
|
||||
wsh->plen = wsh->buffer[1] & 0x7f;
|
||||
*data = (uint8_t *) &wsh->buffer[2];
|
||||
return ws_close(wsh, 1000);
|
||||
}
|
||||
break;
|
||||
case WSOC_CONTINUATION:
|
||||
case WSOC_TEXT:
|
||||
case WSOC_BINARY:
|
||||
case WSOC_PING:
|
||||
case WSOC_PONG:
|
||||
{
|
||||
//int fin = (wsh->buffer[0] >> 7) & 1;
|
||||
int mask = (wsh->buffer[1] >> 7) & 1;
|
||||
|
||||
if (mask) {
|
||||
need += 4;
|
||||
|
||||
if (need > wsh->datalen) {
|
||||
/* too small - protocol err */
|
||||
*oc = WSOC_CLOSE;
|
||||
return ws_close(wsh, WS_PROTO_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
wsh->plen = wsh->buffer[1] & 0x7f;
|
||||
wsh->payload = &wsh->buffer[2];
|
||||
|
||||
if (wsh->plen == 127) {
|
||||
uint64_t *u64;
|
||||
|
||||
need += 8;
|
||||
|
||||
if (need > wsh->datalen) {
|
||||
/* too small - protocol err */
|
||||
*oc = WSOC_CLOSE;
|
||||
return ws_close(wsh, WS_PROTO_ERR);
|
||||
}
|
||||
|
||||
u64 = (uint64_t *) wsh->payload;
|
||||
wsh->payload += 8;
|
||||
|
||||
wsh->plen = ntohl((u_long)*u64);
|
||||
|
||||
} else if (wsh->plen == 126) {
|
||||
uint16_t *u16;
|
||||
|
||||
need += 2;
|
||||
|
||||
if (need > wsh->datalen) {
|
||||
/* too small - protocol err */
|
||||
*oc = WSOC_CLOSE;
|
||||
return ws_close(wsh, WS_PROTO_ERR);
|
||||
}
|
||||
|
||||
u16 = (uint16_t *) wsh->payload;
|
||||
wsh->payload += 2;
|
||||
wsh->plen = ntohs(*u16);
|
||||
}
|
||||
|
||||
if (mask) {
|
||||
maskp = (char *)wsh->payload;
|
||||
wsh->payload += 4;
|
||||
}
|
||||
|
||||
need = (wsh->plen - (wsh->datalen - need));
|
||||
|
||||
if (need < 0) {
|
||||
/* invalid read - protocol err .. */
|
||||
*oc = WSOC_CLOSE;
|
||||
return ws_close(wsh, WS_PROTO_ERR);
|
||||
}
|
||||
|
||||
if ((need + wsh->datalen) > (ssize_t)wsh->buflen) {
|
||||
/* too big - Ain't nobody got time fo' dat */
|
||||
*oc = WSOC_CLOSE;
|
||||
return ws_close(wsh, WS_DATA_TOO_BIG);
|
||||
}
|
||||
|
||||
wsh->rplen = wsh->plen - need;
|
||||
|
||||
while(need) {
|
||||
ssize_t r = ws_raw_read(wsh, wsh->payload + wsh->rplen, need, WS_BLOCK);
|
||||
|
||||
if (r < 1) {
|
||||
/* invalid read - protocol err .. */
|
||||
*oc = WSOC_CLOSE;
|
||||
return ws_close(wsh, WS_PROTO_ERR);
|
||||
}
|
||||
|
||||
wsh->datalen += r;
|
||||
wsh->rplen += r;
|
||||
need -= r;
|
||||
}
|
||||
|
||||
if (mask && maskp) {
|
||||
ssize_t i;
|
||||
|
||||
for (i = 0; i < wsh->datalen; i++) {
|
||||
wsh->payload[i] ^= maskp[i % 4];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (*oc == WSOC_PING) {
|
||||
ws_write_frame(wsh, WSOC_PONG, wsh->payload, wsh->rplen);
|
||||
goto again;
|
||||
}
|
||||
|
||||
|
||||
*(wsh->payload+wsh->rplen) = '\0';
|
||||
*data = (uint8_t *)wsh->payload;
|
||||
|
||||
//printf("READ[%ld][%d]-----------------------------:\n[%s]\n-------------------------------\n", wsh->rplen, *oc, (char *)*data);
|
||||
|
||||
|
||||
return wsh->rplen;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
/* invalid op code - protocol err .. */
|
||||
*oc = WSOC_CLOSE;
|
||||
return ws_close(wsh, WS_PROTO_ERR);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t ws_feed_buf(wsh_t *wsh, void *data, size_t bytes)
|
||||
{
|
||||
|
||||
if (bytes + wsh->wdatalen > wsh->buflen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(wsh->wbuffer + wsh->wdatalen, data, bytes);
|
||||
|
||||
wsh->wdatalen += bytes;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
ssize_t ws_send_buf(wsh_t *wsh, ws_opcode_t oc)
|
||||
{
|
||||
ssize_t r = 0;
|
||||
|
||||
if (!wsh->wdatalen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = ws_write_frame(wsh, oc, wsh->wbuffer, wsh->wdatalen);
|
||||
|
||||
wsh->wdatalen = 0;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
ssize_t ws_write_frame(wsh_t *wsh, ws_opcode_t oc, void *data, size_t bytes)
|
||||
{
|
||||
uint8_t hdr[14] = { 0 };
|
||||
size_t hlen = 2;
|
||||
|
||||
if (wsh->down) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
//printf("WRITE[%ld]-----------------------------:\n[%s]\n-----------------------------------\n", bytes, (char *) data);
|
||||
|
||||
hdr[0] = (uint8_t)(oc | 0x80);
|
||||
|
||||
if (bytes < 126) {
|
||||
hdr[1] = (uint8_t)bytes;
|
||||
} else if (bytes < 0x10000) {
|
||||
uint16_t *u16;
|
||||
|
||||
hdr[1] = 126;
|
||||
hlen += 2;
|
||||
|
||||
u16 = (uint16_t *) &hdr[2];
|
||||
*u16 = htons((uint16_t) bytes);
|
||||
|
||||
} else {
|
||||
uint64_t *u64;
|
||||
|
||||
hdr[1] = 127;
|
||||
hlen += 8;
|
||||
|
||||
u64 = (uint64_t *) &hdr[2];
|
||||
*u64 = htonl(bytes);
|
||||
}
|
||||
|
||||
if (ws_raw_write(wsh, (void *) &hdr[0], hlen) != (ssize_t)hlen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ws_raw_write(wsh, data, bytes) != (ssize_t)bytes) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
int xp_errno(void)
|
||||
{
|
||||
return WSAGetLastError();
|
||||
}
|
||||
|
||||
int xp_is_blocking(int errcode)
|
||||
{
|
||||
return errcode == WSAEWOULDBLOCK || errcode == WSAEINPROGRESS;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int xp_errno(void)
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
|
||||
int xp_is_blocking(int errcode)
|
||||
{
|
||||
return errcode == EAGAIN || errcode == EWOULDBLOCK || errcode == EINPROGRESS || errcode == EINTR || errcode == ETIMEDOUT;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,120 @@
|
|||
#ifndef _WS_H
|
||||
#define _WS_H
|
||||
|
||||
//#define WSS_STANDALONE 1
|
||||
|
||||
#define WEBSOCKET_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
|
||||
#define B64BUFFLEN 1024
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifndef _MSC_VER
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
#else
|
||||
#pragma warning(disable:4996)
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
//#include "sha1.h"
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define strncasecmp _strnicmp
|
||||
#define snprintf _snprintf
|
||||
#ifdef _WIN64
|
||||
#define WS_SSIZE_T __int64
|
||||
#elif _MSC_VER >= 1400
|
||||
#define WS_SSIZE_T __int32 __w64
|
||||
#else
|
||||
#define WS_SSIZE_T __int32
|
||||
#endif
|
||||
typedef WS_SSIZE_T ssize_t;
|
||||
#endif
|
||||
|
||||
|
||||
struct ws_globals_s {
|
||||
const SSL_METHOD *ssl_method;
|
||||
SSL_CTX *ssl_ctx;
|
||||
char cert[512];
|
||||
char key[512];
|
||||
};
|
||||
|
||||
extern struct ws_globals_s ws_globals;
|
||||
|
||||
typedef int ws_socket_t;
|
||||
#define ws_sock_invalid -1
|
||||
|
||||
|
||||
typedef enum {
|
||||
WS_NONE = 0,
|
||||
WS_NORMAL = 1000,
|
||||
WS_PROTO_ERR = 1002,
|
||||
WS_DATA_TOO_BIG = 1009
|
||||
} ws_cause_t;
|
||||
|
||||
typedef enum {
|
||||
WSOC_CONTINUATION = 0x0,
|
||||
WSOC_TEXT = 0x1,
|
||||
WSOC_BINARY = 0x2,
|
||||
WSOC_CLOSE = 0x8,
|
||||
WSOC_PING = 0x9,
|
||||
WSOC_PONG = 0xA
|
||||
} ws_opcode_t;
|
||||
|
||||
typedef struct wsh_s {
|
||||
ws_socket_t sock;
|
||||
char buffer[65536];
|
||||
char wbuffer[65536];
|
||||
size_t buflen;
|
||||
ssize_t datalen;
|
||||
ssize_t wdatalen;
|
||||
char *payload;
|
||||
ssize_t plen;
|
||||
ssize_t rplen;
|
||||
SSL *ssl;
|
||||
int handshake;
|
||||
uint8_t down;
|
||||
int secure;
|
||||
uint8_t close_sock;
|
||||
SSL_CTX *ssl_ctx;
|
||||
int block;
|
||||
int sanity;
|
||||
int secure_established;
|
||||
int logical_established;
|
||||
int x;
|
||||
} wsh_t;
|
||||
|
||||
ssize_t ws_send_buf(wsh_t *wsh, ws_opcode_t oc);
|
||||
ssize_t ws_feed_buf(wsh_t *wsh, void *data, size_t bytes);
|
||||
|
||||
|
||||
ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes, int block);
|
||||
ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes);
|
||||
ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data);
|
||||
ssize_t ws_write_frame(wsh_t *wsh, ws_opcode_t oc, void *data, size_t bytes);
|
||||
int ws_init(wsh_t *wsh, ws_socket_t sock, SSL_CTX *ssl_ctx, int close_sock, int block);
|
||||
ssize_t ws_close(wsh_t *wsh, int16_t reason);
|
||||
void ws_destroy(wsh_t *wsh);
|
||||
void init_ssl(void);
|
||||
void deinit_ssl(void);
|
||||
int xp_errno(void);
|
||||
int xp_is_blocking(int errcode);
|
||||
|
||||
|
||||
|
||||
#ifndef _MSC_VER
|
||||
static inline uint64_t get_unaligned_uint64(const void *p)
|
||||
{
|
||||
const struct { uint64_t d; } __attribute__((packed)) *pp = p;
|
||||
return pp->d;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue