This commit is contained in:
Michael Jerris
2012-08-08 17:05:01 -05:00
committed by Ken Rice
parent 83d0f5055e
commit c920135658
82 changed files with 34654 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
lib_LTLIBRARIES=libwebsockets.la
include_HEADERS=libwebsockets.h
dist_libwebsockets_la_SOURCES=libwebsockets.c \
handshake.c \
parsers.c \
libwebsockets.h \
base64-decode.c \
client-handshake.c \
extension.c \
extension-deflate-stream.c \
private-libwebsockets.h
if EXT_GOOGLE_MUX
dist_libwebsockets_la_SOURCES += extension-x-google-mux.c
endif
if LIBCRYPTO
else
dist_libwebsockets_la_SOURCES += md5.c sha-1.c
endif
libwebsockets_la_CFLAGS:=-Wall -std=gnu99 -pedantic
libwebsockets_la_LDFLAGS:=
if MINGW
libwebsockets_la_CFLAGS+= -w -I../win32port/win32helpers -I ../win32port/zlib/
libwebsockets_la_LDFLAGS+= -lm -luser32 -ladvapi32 -lkernel32 -lgcc
else
libwebsockets_la_CFLAGS+= -rdynamic -fPIC -Werror
libwebsockets_la_LDFLAGS+= -version-info 0:3
endif
libwebsockets_la_CFLAGS+= -c \
-DINSTALL_DATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\"
libwebsockets_la_LDFLAGS+= -lz
all-local:
../scripts/kernel-doc -html \
libwebsockets.c \
parsers.c \
client-handshake.c \
libwebsockets.h \
> ../libwebsockets-api-doc.html

View File

@@ -0,0 +1,665 @@
# Makefile.in generated by automake 1.11.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
# Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@EXT_GOOGLE_MUX_TRUE@am__append_1 = extension-x-google-mux.c
@LIBCRYPTO_FALSE@am__append_2 = md5.c sha-1.c
@MINGW_TRUE@am__append_3 = -w -I../win32port/win32helpers -I ../win32port/zlib/
@MINGW_TRUE@am__append_4 = -lm -luser32 -ladvapi32 -lkernel32 -lgcc
@MINGW_FALSE@am__append_5 = -rdynamic -fPIC -Werror
@MINGW_FALSE@am__append_6 = -version-info 0:3
subdir = lib
DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libwebsockets_la_LIBADD =
am__dist_libwebsockets_la_SOURCES_DIST = libwebsockets.c handshake.c \
parsers.c libwebsockets.h base64-decode.c client-handshake.c \
extension.c extension-deflate-stream.c private-libwebsockets.h \
extension-x-google-mux.c md5.c sha-1.c
@EXT_GOOGLE_MUX_TRUE@am__objects_1 = libwebsockets_la-extension-x-google-mux.lo
@LIBCRYPTO_FALSE@am__objects_2 = libwebsockets_la-md5.lo \
@LIBCRYPTO_FALSE@ libwebsockets_la-sha-1.lo
dist_libwebsockets_la_OBJECTS = libwebsockets_la-libwebsockets.lo \
libwebsockets_la-handshake.lo libwebsockets_la-parsers.lo \
libwebsockets_la-base64-decode.lo \
libwebsockets_la-client-handshake.lo \
libwebsockets_la-extension.lo \
libwebsockets_la-extension-deflate-stream.lo $(am__objects_1) \
$(am__objects_2)
libwebsockets_la_OBJECTS = $(dist_libwebsockets_la_OBJECTS)
libwebsockets_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libwebsockets_la_CFLAGS) \
$(CFLAGS) $(libwebsockets_la_LDFLAGS) $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(dist_libwebsockets_la_SOURCES)
DIST_SOURCES = $(am__dist_libwebsockets_la_SOURCES_DIST)
HEADERS = $(include_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
clientcertdir = @clientcertdir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
lib_LTLIBRARIES = libwebsockets.la
include_HEADERS = libwebsockets.h
dist_libwebsockets_la_SOURCES = libwebsockets.c handshake.c parsers.c \
libwebsockets.h base64-decode.c client-handshake.c extension.c \
extension-deflate-stream.c private-libwebsockets.h \
$(am__append_1) $(am__append_2)
libwebsockets_la_CFLAGS := -Wall -std=gnu99 -pedantic $(am__append_3) \
$(am__append_5) -c -DINSTALL_DATADIR=\"@datadir@\" \
-DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\"
libwebsockets_la_LDFLAGS := $(am__append_4) $(am__append_6) -lz
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign lib/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libwebsockets.la: $(libwebsockets_la_OBJECTS) $(libwebsockets_la_DEPENDENCIES) $(EXTRA_libwebsockets_la_DEPENDENCIES)
$(libwebsockets_la_LINK) -rpath $(libdir) $(libwebsockets_la_OBJECTS) $(libwebsockets_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebsockets_la-base64-decode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebsockets_la-client-handshake.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebsockets_la-extension-deflate-stream.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebsockets_la-extension-x-google-mux.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebsockets_la-extension.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebsockets_la-handshake.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebsockets_la-libwebsockets.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebsockets_la-md5.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebsockets_la-parsers.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebsockets_la-sha-1.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
libwebsockets_la-libwebsockets.lo: libwebsockets.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -MT libwebsockets_la-libwebsockets.lo -MD -MP -MF $(DEPDIR)/libwebsockets_la-libwebsockets.Tpo -c -o libwebsockets_la-libwebsockets.lo `test -f 'libwebsockets.c' || echo '$(srcdir)/'`libwebsockets.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libwebsockets_la-libwebsockets.Tpo $(DEPDIR)/libwebsockets_la-libwebsockets.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libwebsockets.c' object='libwebsockets_la-libwebsockets.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -c -o libwebsockets_la-libwebsockets.lo `test -f 'libwebsockets.c' || echo '$(srcdir)/'`libwebsockets.c
libwebsockets_la-handshake.lo: handshake.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -MT libwebsockets_la-handshake.lo -MD -MP -MF $(DEPDIR)/libwebsockets_la-handshake.Tpo -c -o libwebsockets_la-handshake.lo `test -f 'handshake.c' || echo '$(srcdir)/'`handshake.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libwebsockets_la-handshake.Tpo $(DEPDIR)/libwebsockets_la-handshake.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='handshake.c' object='libwebsockets_la-handshake.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -c -o libwebsockets_la-handshake.lo `test -f 'handshake.c' || echo '$(srcdir)/'`handshake.c
libwebsockets_la-parsers.lo: parsers.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -MT libwebsockets_la-parsers.lo -MD -MP -MF $(DEPDIR)/libwebsockets_la-parsers.Tpo -c -o libwebsockets_la-parsers.lo `test -f 'parsers.c' || echo '$(srcdir)/'`parsers.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libwebsockets_la-parsers.Tpo $(DEPDIR)/libwebsockets_la-parsers.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='parsers.c' object='libwebsockets_la-parsers.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -c -o libwebsockets_la-parsers.lo `test -f 'parsers.c' || echo '$(srcdir)/'`parsers.c
libwebsockets_la-base64-decode.lo: base64-decode.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -MT libwebsockets_la-base64-decode.lo -MD -MP -MF $(DEPDIR)/libwebsockets_la-base64-decode.Tpo -c -o libwebsockets_la-base64-decode.lo `test -f 'base64-decode.c' || echo '$(srcdir)/'`base64-decode.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libwebsockets_la-base64-decode.Tpo $(DEPDIR)/libwebsockets_la-base64-decode.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='base64-decode.c' object='libwebsockets_la-base64-decode.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -c -o libwebsockets_la-base64-decode.lo `test -f 'base64-decode.c' || echo '$(srcdir)/'`base64-decode.c
libwebsockets_la-client-handshake.lo: client-handshake.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -MT libwebsockets_la-client-handshake.lo -MD -MP -MF $(DEPDIR)/libwebsockets_la-client-handshake.Tpo -c -o libwebsockets_la-client-handshake.lo `test -f 'client-handshake.c' || echo '$(srcdir)/'`client-handshake.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libwebsockets_la-client-handshake.Tpo $(DEPDIR)/libwebsockets_la-client-handshake.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client-handshake.c' object='libwebsockets_la-client-handshake.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -c -o libwebsockets_la-client-handshake.lo `test -f 'client-handshake.c' || echo '$(srcdir)/'`client-handshake.c
libwebsockets_la-extension.lo: extension.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -MT libwebsockets_la-extension.lo -MD -MP -MF $(DEPDIR)/libwebsockets_la-extension.Tpo -c -o libwebsockets_la-extension.lo `test -f 'extension.c' || echo '$(srcdir)/'`extension.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libwebsockets_la-extension.Tpo $(DEPDIR)/libwebsockets_la-extension.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='extension.c' object='libwebsockets_la-extension.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -c -o libwebsockets_la-extension.lo `test -f 'extension.c' || echo '$(srcdir)/'`extension.c
libwebsockets_la-extension-deflate-stream.lo: extension-deflate-stream.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -MT libwebsockets_la-extension-deflate-stream.lo -MD -MP -MF $(DEPDIR)/libwebsockets_la-extension-deflate-stream.Tpo -c -o libwebsockets_la-extension-deflate-stream.lo `test -f 'extension-deflate-stream.c' || echo '$(srcdir)/'`extension-deflate-stream.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libwebsockets_la-extension-deflate-stream.Tpo $(DEPDIR)/libwebsockets_la-extension-deflate-stream.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='extension-deflate-stream.c' object='libwebsockets_la-extension-deflate-stream.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -c -o libwebsockets_la-extension-deflate-stream.lo `test -f 'extension-deflate-stream.c' || echo '$(srcdir)/'`extension-deflate-stream.c
libwebsockets_la-extension-x-google-mux.lo: extension-x-google-mux.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -MT libwebsockets_la-extension-x-google-mux.lo -MD -MP -MF $(DEPDIR)/libwebsockets_la-extension-x-google-mux.Tpo -c -o libwebsockets_la-extension-x-google-mux.lo `test -f 'extension-x-google-mux.c' || echo '$(srcdir)/'`extension-x-google-mux.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libwebsockets_la-extension-x-google-mux.Tpo $(DEPDIR)/libwebsockets_la-extension-x-google-mux.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='extension-x-google-mux.c' object='libwebsockets_la-extension-x-google-mux.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -c -o libwebsockets_la-extension-x-google-mux.lo `test -f 'extension-x-google-mux.c' || echo '$(srcdir)/'`extension-x-google-mux.c
libwebsockets_la-md5.lo: md5.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -MT libwebsockets_la-md5.lo -MD -MP -MF $(DEPDIR)/libwebsockets_la-md5.Tpo -c -o libwebsockets_la-md5.lo `test -f 'md5.c' || echo '$(srcdir)/'`md5.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libwebsockets_la-md5.Tpo $(DEPDIR)/libwebsockets_la-md5.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='md5.c' object='libwebsockets_la-md5.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -c -o libwebsockets_la-md5.lo `test -f 'md5.c' || echo '$(srcdir)/'`md5.c
libwebsockets_la-sha-1.lo: sha-1.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -MT libwebsockets_la-sha-1.lo -MD -MP -MF $(DEPDIR)/libwebsockets_la-sha-1.Tpo -c -o libwebsockets_la-sha-1.lo `test -f 'sha-1.c' || echo '$(srcdir)/'`sha-1.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libwebsockets_la-sha-1.Tpo $(DEPDIR)/libwebsockets_la-sha-1.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sha-1.c' object='libwebsockets_la-sha-1.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_la_CFLAGS) $(CFLAGS) -c -o libwebsockets_la-sha-1.lo `test -f 'sha-1.c' || echo '$(srcdir)/'`sha-1.c
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-includeHEADERS: $(include_HEADERS)
@$(NORMAL_INSTALL)
test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
done
uninstall-includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS) all-local
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-includeHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am all-local check check-am clean \
clean-generic clean-libLTLIBRARIES clean-libtool ctags \
distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am \
install-includeHEADERS install-info install-info-am \
install-libLTLIBRARIES install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-includeHEADERS \
uninstall-libLTLIBRARIES
all-local:
../scripts/kernel-doc -html \
libwebsockets.c \
parsers.c \
client-handshake.c \
libwebsockets.h \
> ../libwebsockets-api-doc.html
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@@ -0,0 +1,188 @@
/*
* This code originally came from here
*
* http://base64.sourceforge.net/b64.c
*
* with the following license:
*
* LICENCE: Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the
* Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall
* be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
* KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
* OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* VERSION HISTORY:
* Bob Trower 08/04/01 -- Create Version 0.00.00B
*
* I cleaned it up quite a bit to match the (linux kernel) style of the rest
* of libwebsockets; this version is under LGPL2 like the rest of libwebsockets
* since he explictly allows sublicensing, but I give the URL above so you can
* get the original with Bob's super-liberal terms directly if you prefer.
*/
#include <stdio.h>
#include <string.h>
static const char encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz0123456789+/";
static const char decode[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW"
"$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
int
lws_b64_encode_string(const char *in, int in_len, char *out, int out_size)
{
unsigned char triple[3];
int i;
int len;
int line = 0;
int done = 0;
while (in_len) {
len = 0;
for (i = 0; i < 3; i++) {
if (in_len) {
triple[i] = *in++;
len++;
in_len--;
} else
triple[i] = 0;
}
if (!len)
continue;
if (done + 4 >= out_size)
return -1;
*out++ = encode[triple[0] >> 2];
*out++ = encode[((triple[0] & 0x03) << 4) |
((triple[1] & 0xf0) >> 4)];
*out++ = (len > 1 ? encode[((triple[1] & 0x0f) << 2) |
((triple[2] & 0xc0) >> 6)] : '=');
*out++ = (len > 2 ? encode[triple[2] & 0x3f] : '=');
done += 4;
line += 4;
}
if (done + 1 >= out_size)
return -1;
*out++ = '\0';
return done;
}
/*
* returns length of decoded string in out, or -1 if out was too small
* according to out_size
*/
int
lws_b64_decode_string(const char *in, char *out, int out_size)
{
int len;
int i;
int done = 0;
unsigned char v;
unsigned char quad[4];
while (*in) {
len = 0;
for (i = 0; i < 4 && *in; i++) {
v = 0;
while (*in && !v) {
v = *in++;
v = (v < 43 || v > 122) ? 0 : decode[v - 43];
if (v)
v = (v == '$') ? 0 : v - 61;
if (*in) {
len++;
if (v)
quad[i] = v - 1;
} else
quad[i] = 0;
}
}
if (!len)
continue;
if (out_size < (done + len - 1))
/* out buffer is too small */
return -1;
if (len >= 2)
*out++ = quad[0] << 2 | quad[1] >> 4;
if (len >= 3)
*out++ = quad[1] << 4 | quad[2] >> 2;
if (len >= 4)
*out++ = ((quad[2] << 6) & 0xc0) | quad[3];
done += len - 1;
}
if (done + 1 >= out_size)
return -1;
*out++ = '\0';
return done;
}
int
lws_b64_selftest(void)
{
char buf[64];
int n;
int test;
static const char * const plaintext[] = {
"sanity check base 64"
};
static const char * const coded[] = {
"c2FuaXR5IGNoZWNrIGJhc2UgNjQ="
};
for (test = 0; test < sizeof plaintext / sizeof(plaintext[0]); test++) {
buf[sizeof(buf) - 1] = '\0';
n = lws_b64_encode_string(plaintext[test],
strlen(plaintext[test]), buf, sizeof buf);
if (n != strlen(coded[test]) || strcmp(buf, coded[test])) {
fprintf(stderr, "Failed lws_b64 encode selftest "
"%d result '%s' %d\n", test, buf, n);
return -1;
}
buf[sizeof(buf) - 1] = '\0';
n = lws_b64_decode_string(coded[test], buf, sizeof buf);
if (n != strlen(plaintext[test]) ||
strcmp(buf, plaintext[test])) {
fprintf(stderr, "Failed lws_b64 decode selftest "
"%d result '%s' %d\n", test, buf, n);
return -1;
}
}
return 0;
}

View File

@@ -0,0 +1,408 @@
#include "private-libwebsockets.h"
struct libwebsocket *__libwebsocket_client_connect_2(
struct libwebsocket_context *context,
struct libwebsocket *wsi
) {
struct pollfd pfd;
struct timeval tv;
struct hostent *server_hostent;
struct sockaddr_in server_addr;
int n;
int plen = 0;
char pkt[512];
int opt = 1;
#if defined(__APPLE__)
struct protoent *tcp_proto;
#endif
debug("__libwebsocket_client_connect_2\n");
wsi->candidate_children_list = NULL;
/*
* proxy?
*/
if (context->http_proxy_port) {
plen = sprintf(pkt, "CONNECT %s:%u HTTP/1.0\x0d\x0a"
"User-agent: libwebsockets\x0d\x0a"
/*Proxy-authorization: basic aGVsbG86d29ybGQ= */
"\x0d\x0a", wsi->c_address, wsi->c_port);
/* OK from now on we talk via the proxy */
free(wsi->c_address);
wsi->c_address = strdup(context->http_proxy_address);
wsi->c_port = context->http_proxy_port;
}
/*
* prepare the actual connection (to the proxy, if any)
*/
debug("__libwebsocket_client_connect_2: address %s", wsi->c_address);
server_hostent = gethostbyname(wsi->c_address);
if (server_hostent == NULL) {
fprintf(stderr, "Unable to get host name from %s\n",
wsi->c_address);
goto oom4;
}
wsi->sock = socket(AF_INET, SOCK_STREAM, 0);
if (wsi->sock < 0) {
fprintf(stderr, "Unable to open socket\n");
goto oom4;
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(wsi->c_port);
server_addr.sin_addr = *((struct in_addr *)server_hostent->h_addr);
bzero(&server_addr.sin_zero, 8);
/* Disable Nagle */
#if !defined(__APPLE__)
setsockopt(wsi->sock, SOL_TCP, TCP_NODELAY,
(const void *)&opt, sizeof(opt));
#else
tcp_proto = getprotobyname("TCP");
setsockopt(wsi->sock, tcp_proto->p_proto, TCP_NODELAY,
&opt, sizeof(opt));
#endif
/* Set receiving timeout */
tv.tv_sec = 0;
tv.tv_usec = 100 * 1000;
setsockopt(wsi->sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv);
if (connect(wsi->sock, (struct sockaddr *)&server_addr,
sizeof(struct sockaddr)) == -1) {
fprintf(stderr, "Connect failed\n");
#ifdef WIN32
closesocket(wsi->sock);
#else
close(wsi->sock);
#endif
goto oom4;
}
debug("connected\n");
/* into fd -> wsi hashtable */
insert_wsi(context, wsi);
/* into internal poll list */
context->fds[context->fds_count].fd = wsi->sock;
context->fds[context->fds_count].revents = 0;
context->fds[context->fds_count++].events = POLLIN;
/* external POLL support via protocol 0 */
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_ADD_POLL_FD,
(void *)(long)wsi->sock, NULL, POLLIN);
/* we are connected to server, or proxy */
if (context->http_proxy_port) {
n = send(wsi->sock, pkt, plen, 0);
if (n < 0) {
#ifdef WIN32
closesocket(wsi->sock);
#else
close(wsi->sock);
#endif
fprintf(stderr, "ERROR writing to proxy socket\n");
goto bail1;
}
libwebsocket_set_timeout(wsi,
PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE, 5);
wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY;
return wsi;
}
/*
* provoke service to issue the handshake directly
* we need to do it this way because in the proxy case, this is the
* next state and executed only if and when we get a good proxy
* response inside the state machine
*/
wsi->mode = LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE;
pfd.fd = wsi->sock;
pfd.revents = POLLIN;
if (libwebsocket_service_fd(context, &pfd) < 0)
goto oom4;
return wsi;
oom4:
if (wsi->c_protocol)
free(wsi->c_protocol);
if (wsi->c_origin)
free(wsi->c_origin);
free(wsi->c_host);
free(wsi->c_path);
bail1:
free(wsi);
return NULL;
}
/**
* libwebsocket_client_connect() - Connect to another websocket server
* @context: Websocket context
* @address: Remote server address, eg, "myserver.com"
* @port: Port to connect to on the remote server, eg, 80
* @ssl_connection: 0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self
* signed certs
* @path: Websocket path on server
* @host: Hostname on server
* @origin: Socket origin name
* @protocol: Comma-separated list of protocols being asked for from
* the server, or just one. The server will pick the one it
* likes best.
* @ietf_version_or_minus_one: -1 to ask to connect using the default, latest
* protocol supported, or the specific protocol ordinal
*
* This function creates a connection to a remote server
*/
struct libwebsocket *
libwebsocket_client_connect(struct libwebsocket_context *context,
const char *address,
int port,
int ssl_connection,
const char *path,
const char *host,
const char *origin,
const char *protocol,
int ietf_version_or_minus_one)
{
struct libwebsocket *wsi;
int n;
int m;
struct libwebsocket_extension *ext;
int handled;
#ifndef LWS_OPENSSL_SUPPORT
if (ssl_connection) {
fprintf(stderr, "libwebsockets not configured for ssl\n");
return NULL;
}
#endif
wsi = malloc(sizeof(struct libwebsocket));
if (wsi == NULL)
goto bail1;
memset(wsi, 0, sizeof *wsi);
/* -1 means just use latest supported */
if (ietf_version_or_minus_one == -1)
ietf_version_or_minus_one = SPEC_LATEST_SUPPORTED;
wsi->ietf_spec_revision = ietf_version_or_minus_one;
wsi->name_buffer_pos = 0;
wsi->user_space = NULL;
wsi->state = WSI_STATE_CLIENT_UNCONNECTED;
wsi->pings_vs_pongs = 0;
wsi->protocol = NULL;
wsi->pending_timeout = NO_PENDING_TIMEOUT;
wsi->count_active_extensions = 0;
#ifdef LWS_OPENSSL_SUPPORT
wsi->use_ssl = ssl_connection;
#endif
wsi->c_port = port;
wsi->c_address = strdup(address);
/* copy parameters over so state machine has access */
wsi->c_path = malloc(strlen(path) + 1);
if (wsi->c_path == NULL)
goto bail1;
strcpy(wsi->c_path, path);
wsi->c_host = malloc(strlen(host) + 1);
if (wsi->c_host == NULL)
goto oom1;
strcpy(wsi->c_host, host);
if (origin) {
wsi->c_origin = malloc(strlen(origin) + 1);
strcpy(wsi->c_origin, origin);
if (wsi->c_origin == NULL)
goto oom2;
} else
wsi->c_origin = NULL;
wsi->c_callback = NULL;
if (protocol) {
const char *pc;
struct libwebsocket_protocols *pp;
wsi->c_protocol = malloc(strlen(protocol) + 1);
if (wsi->c_protocol == NULL)
goto oom3;
strcpy(wsi->c_protocol, protocol);
pc = protocol;
while (*pc && *pc != ',')
pc++;
n = pc - protocol;
pp = context->protocols;
while (pp->name && !wsi->c_callback) {
if (!strncmp(protocol, pp->name, n))
wsi->c_callback = pp->callback;
pp++;
}
} else
wsi->c_protocol = NULL;
if (!wsi->c_callback)
wsi->c_callback = context->protocols[0].callback;
/* set up appropriate masking */
wsi->xor_mask = xor_no_mask;
switch (wsi->ietf_spec_revision) {
case 0:
break;
case 4:
wsi->xor_mask = xor_mask_04;
break;
case 5:
case 6:
case 7:
case 8:
case 13:
wsi->xor_mask = xor_mask_05;
break;
default:
fprintf(stderr,
"Client ietf version %d not supported\n",
wsi->ietf_spec_revision);
goto oom4;
}
/* force no mask if he asks for that though */
if (context->options & LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK)
wsi->xor_mask = xor_no_mask;
for (n = 0; n < WSI_TOKEN_COUNT; n++) {
wsi->utf8_token[n].token = NULL;
wsi->utf8_token[n].token_len = 0;
}
/*
* Check with each extension if it is able to route and proxy this
* connection for us. For example, an extension like x-google-mux
* can handle this and then we don't need an actual socket for this
* connection.
*/
handled = 0;
ext = context->extensions;
n = 0;
while (ext && ext->callback && !handled) {
m = ext->callback(context, ext, wsi,
LWS_EXT_CALLBACK_CAN_PROXY_CLIENT_CONNECTION,
(void *)(long)n, (void *)address, port);
if (m)
handled = 1;
ext++;
n++;
}
if (handled) {
debug("libwebsocket_client_connect: ext handling conn\n");
libwebsocket_set_timeout(wsi,
PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE, 5);
wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT;
return wsi;
}
debug("libwebsocket_client_connect: direct conn\n");
return __libwebsocket_client_connect_2(context, wsi);
oom4:
if (wsi->c_protocol)
free(wsi->c_protocol);
oom3:
if (wsi->c_origin)
free(wsi->c_origin);
oom2:
free(wsi->c_host);
oom1:
free(wsi->c_path);
bail1:
free(wsi);
return NULL;
}
/**
* libwebsocket_client_connect_extended() - Connect to another websocket server
* @context: Websocket context
* @address: Remote server address, eg, "myserver.com"
* @port: Port to connect to on the remote server, eg, 80
* @ssl_connection: 0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self
* signed certs
* @path: Websocket path on server
* @host: Hostname on server
* @origin: Socket origin name
* @protocol: Comma-separated list of protocols being asked for from
* the server, or just one. The server will pick the one it
* likes best.
* @ietf_version_or_minus_one: -1 to ask to connect using the default, latest
* protocol supported, or the specific protocol ordinal
* @userdata: Pre-allocated user data
*
* This function creates a connection to a remote server
*/
struct libwebsocket *
libwebsocket_client_connect_extended(struct libwebsocket_context *context,
const char *address,
int port,
int ssl_connection,
const char *path,
const char *host,
const char *origin,
const char *protocol,
int ietf_version_or_minus_one,
void *userdata)
{
struct libwebsocket *ws =
libwebsocket_client_connect(context, address, port, ssl_connection, path, host, origin, protocol, ietf_version_or_minus_one) ;
if (ws && !ws->user_space && userdata)
ws->user_space = userdata ;
return ws ;
}

View File

@@ -0,0 +1,150 @@
#include "private-libwebsockets.h"
#include "extension-deflate-stream.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
#define LWS_ZLIB_WINDOW_BITS 15
#define LWS_ZLIB_MEMLEVEL 8
int lws_extension_callback_deflate_stream(
struct libwebsocket_context *context,
struct libwebsocket_extension *ext,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons reason,
void *user, void *in, size_t len)
{
struct lws_ext_deflate_stream_conn *conn =
(struct lws_ext_deflate_stream_conn *)user;
int n;
struct lws_tokens *eff_buf = (struct lws_tokens *)in;
switch (reason) {
/*
* for deflate-stream, both client and server sides act the same
*/
case LWS_EXT_CALLBACK_CLIENT_CONSTRUCT:
case LWS_EXT_CALLBACK_CONSTRUCT:
conn->zs_in.zalloc = conn->zs_out.zalloc = Z_NULL;
conn->zs_in.zfree = conn->zs_out.zfree = Z_NULL;
conn->zs_in.opaque = conn->zs_out.opaque = Z_NULL;
n = inflateInit2(&conn->zs_in, -LWS_ZLIB_WINDOW_BITS);
if (n != Z_OK) {
fprintf(stderr, "deflateInit returned %d\n", n);
return 1;
}
n = deflateInit2(&conn->zs_out,
DEFLATE_STREAM_COMPRESSION_LEVEL, Z_DEFLATED,
-LWS_ZLIB_WINDOW_BITS, LWS_ZLIB_MEMLEVEL,
Z_DEFAULT_STRATEGY);
if (n != Z_OK) {
fprintf(stderr, "deflateInit returned %d\n", n);
return 1;
}
debug("zlibs constructed\n");
break;
case LWS_EXT_CALLBACK_DESTROY:
(void)inflateEnd(&conn->zs_in);
(void)deflateEnd(&conn->zs_out);
debug("zlibs destructed\n");
break;
case LWS_EXT_CALLBACK_PACKET_RX_PREPARSE:
/*
* inflate the incoming compressed data
* Notice, length may be 0 and pointer NULL
* in the case we are flushing with nothing new coming in
*/
conn->zs_in.next_in = (unsigned char *)eff_buf->token;
conn->zs_in.avail_in = eff_buf->token_len;
conn->zs_in.next_out = conn->buf;
conn->zs_in.avail_out = sizeof(conn->buf);
n = inflate(&conn->zs_in, Z_SYNC_FLUSH);
switch (n) {
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
/*
* screwed.. close the connection... we will get a
* destroy callback to take care of closing nicely
*/
fprintf(stderr, "zlib error inflate %d\n", n);
return -1;
}
/* rewrite the buffer pointers and length */
eff_buf->token = (char *)conn->buf;
eff_buf->token_len = sizeof(conn->buf) - conn->zs_in.avail_out;
/*
* if we filled the output buffer, signal that we likely have
* more and need to be called again
*/
if (eff_buf->token_len == sizeof(conn->buf))
return 1;
/* we don't need calling again until new input data comes */
return 0;
case LWS_EXT_CALLBACK_FLUSH_PENDING_TX:
case LWS_EXT_CALLBACK_PACKET_TX_PRESEND:
/*
* deflate the outgoing compressed data
*/
conn->zs_out.next_in = (unsigned char *)eff_buf->token;
conn->zs_out.avail_in = eff_buf->token_len;
conn->zs_out.next_out = conn->buf;
conn->zs_out.avail_out = sizeof(conn->buf);
n = Z_PARTIAL_FLUSH;
if (reason == LWS_EXT_CALLBACK_FLUSH_PENDING_TX)
n = Z_FULL_FLUSH;
n = deflate(&conn->zs_out, n);
if (n == Z_STREAM_ERROR) {
/*
* screwed.. close the connection... we will get a
* destroy callback to take care of closing nicely
*/
fprintf(stderr, "zlib error deflate\n");
return -1;
}
/* rewrite the buffer pointers and length */
eff_buf->token = (char *)conn->buf;
eff_buf->token_len = sizeof(conn->buf) - conn->zs_out.avail_out;
/*
* if we filled the output buffer, signal that we likely have
* more and need to be called again... even in deflate case
* we might sometimes need to spill more than came in
*/
if (eff_buf->token_len == sizeof(conn->buf))
return 1;
/* we don't need calling again until new input data comes */
return 0;
default:
break;
}
return 0;
}

View File

@@ -0,0 +1,18 @@
#include <zlib.h>
#define DEFLATE_STREAM_CHUNK 128
#define DEFLATE_STREAM_COMPRESSION_LEVEL 1
struct lws_ext_deflate_stream_conn {
z_stream zs_in;
z_stream zs_out;
unsigned char buf[2000];
};
extern int lws_extension_callback_deflate_stream(
struct libwebsocket_context *context,
struct libwebsocket_extension *ext,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons reason,
void *user, void *in, size_t len);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,96 @@
#if 0
#ifdef WIN32
static
#else
static inline
#endif
void muxdebug(const char *format, ...)
{
va_list ap;
va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap);
}
#else
#ifdef WIN32
static
#else
static inline
#endif
void muxdebug(const char *format, ...)
{
}
#endif
#define MAX_XGM_SUBCHANNELS 8192
enum lws_ext_x_google_mux__parser_states {
LWS_EXT_XGM_STATE__MUX_BLOCK_1,
LWS_EXT_XGM_STATE__MUX_BLOCK_2,
LWS_EXT_XGM_STATE__MUX_BLOCK_3,
LWS_EXT_XGM_STATE__ADDCHANNEL_LEN,
LWS_EXT_XGM_STATE__ADDCHANNEL_LEN16_1,
LWS_EXT_XGM_STATE__ADDCHANNEL_LEN16_2,
LWS_EXT_XGM_STATE__ADDCHANNEL_LEN32_1,
LWS_EXT_XGM_STATE__ADDCHANNEL_LEN32_2,
LWS_EXT_XGM_STATE__ADDCHANNEL_LEN32_3,
LWS_EXT_XGM_STATE__ADDCHANNEL_LEN32_4,
LWS_EXT_XGM_STATE__ADDCHANNEL_HEADERS,
LWS_EXT_XGM_STATE__FLOWCONTROL_1,
LWS_EXT_XGM_STATE__FLOWCONTROL_2,
LWS_EXT_XGM_STATE__FLOWCONTROL_3,
LWS_EXT_XGM_STATE__FLOWCONTROL_4,
LWS_EXT_XGM_STATE__DATA,
};
enum lws_ext_x_goole_mux__mux_opcodes {
LWS_EXT_XGM_OPC__DATA,
LWS_EXT_XGM_OPC__ADDCHANNEL,
LWS_EXT_XGM_OPC__DROPCHANNEL,
LWS_EXT_XGM_OPC__FLOWCONTROL,
LWS_EXT_XGM_OPC__RESERVED_4,
LWS_EXT_XGM_OPC__RESERVED_5,
LWS_EXT_XGM_OPC__RESERVED_6,
LWS_EXT_XGM_OPC__RESERVED_7,
};
/* one of these per context (server or client) */
struct lws_ext_x_google_mux_context {
/*
* these are listing physical connections, not children sharing a
* parent mux physical connection
*/
struct libwebsocket *wsi_muxconns[MAX_CLIENTS];
/*
* when this is < 2, we do not do any mux blocks
* just pure websockets
*/
int active_conns;
};
/* one of these per connection (server or client) */
struct lws_ext_x_google_mux_conn {
enum lws_ext_x_goole_mux__mux_opcodes block_subopcode;
int block_subchannel;
unsigned int length;
enum lws_ext_x_google_mux__parser_states state;
/* child points to the mux wsi using this */
struct libwebsocket *wsi_parent;
int subchannel;
struct libwebsocket *wsi_children[MAX_CLIENTS];
int highest_child_subchannel;
char awaiting_POLLOUT;
int count_children_needing_POLLOUT;
int sticky_mux_used;
int defeat_mux_opcode_wrapping;
int original_ch1_closed;
int ignore_cmd;
};
extern int
lws_extension_callback_x_google_mux(struct libwebsocket_context *context,
struct libwebsocket_extension *ext,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons reason,
void *user, void *in, size_t len);

View File

@@ -0,0 +1,22 @@
#include "private-libwebsockets.h"
#include "extension-deflate-stream.h"
#include "extension-x-google-mux.h"
struct libwebsocket_extension libwebsocket_internal_extensions[] = {
#ifdef LWS_EXT_GOOGLE_MUX
{
"x-google-mux",
lws_extension_callback_x_google_mux,
sizeof (struct lws_ext_x_google_mux_conn)
},
#endif
{
"deflate-stream",
lws_extension_callback_deflate_stream,
sizeof (struct lws_ext_deflate_stream_conn)
},
{ /* terminator */
NULL, NULL, 0
}
};

View File

@@ -0,0 +1,722 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include "private-libwebsockets.h"
#define LWS_CPYAPP(ptr, str) { strcpy(ptr, str); ptr += strlen(str); }
#define LWS_CPYAPP_TOKEN(ptr, tok) { strcpy(p, wsi->utf8_token[tok].token); \
p += wsi->utf8_token[tok].token_len; }
static int
interpret_key(const char *key, unsigned long *result)
{
char digits[20];
int digit_pos = 0;
const char *p = key;
unsigned int spaces = 0;
unsigned long acc = 0;
int rem = 0;
while (*p) {
if (!isdigit(*p)) {
p++;
continue;
}
if (digit_pos == sizeof(digits) - 1)
return -1;
digits[digit_pos++] = *p++;
}
digits[digit_pos] = '\0';
if (!digit_pos)
return -2;
while (*key) {
if (*key == ' ')
spaces++;
key++;
}
if (!spaces)
return -3;
p = &digits[0];
while (*p) {
rem = (rem * 10) + ((*p++) - '0');
acc = (acc * 10) + (rem / spaces);
rem -= (rem / spaces) * spaces;
}
if (rem) {
fprintf(stderr, "nonzero handshake remainder\n");
return -1;
}
*result = acc;
return 0;
}
static int
handshake_00(struct libwebsocket_context *context, struct libwebsocket *wsi)
{
unsigned long key1, key2;
unsigned char sum[16];
char *response;
char *p;
int n;
/* Confirm we have all the necessary pieces */
if (!wsi->utf8_token[WSI_TOKEN_ORIGIN].token_len ||
!wsi->utf8_token[WSI_TOKEN_HOST].token_len ||
!wsi->utf8_token[WSI_TOKEN_CHALLENGE].token_len ||
!wsi->utf8_token[WSI_TOKEN_KEY1].token_len ||
!wsi->utf8_token[WSI_TOKEN_KEY2].token_len)
/* completed header processing, but missing some bits */
goto bail;
/* allocate the per-connection user memory (if any) */
if (wsi->protocol->per_session_data_size &&
!libwebsocket_ensure_user_space(wsi))
goto bail;
/* create the response packet */
/* make a buffer big enough for everything */
response = malloc(256 +
wsi->utf8_token[WSI_TOKEN_UPGRADE].token_len +
wsi->utf8_token[WSI_TOKEN_CONNECTION].token_len +
wsi->utf8_token[WSI_TOKEN_HOST].token_len +
wsi->utf8_token[WSI_TOKEN_ORIGIN].token_len +
wsi->utf8_token[WSI_TOKEN_GET_URI].token_len +
wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len);
if (!response) {
fprintf(stderr, "Out of memory for response buffer\n");
goto bail;
}
p = response;
LWS_CPYAPP(p, "HTTP/1.1 101 WebSocket Protocol Handshake\x0d\x0a"
"Upgrade: WebSocket\x0d\x0a"
"Connection: Upgrade\x0d\x0a"
"Sec-WebSocket-Origin: ");
strcpy(p, wsi->utf8_token[WSI_TOKEN_ORIGIN].token);
p += wsi->utf8_token[WSI_TOKEN_ORIGIN].token_len;
#ifdef LWS_OPENSSL_SUPPORT
if (wsi->ssl) {
LWS_CPYAPP(p, "\x0d\x0aSec-WebSocket-Location: wss://");
} else {
LWS_CPYAPP(p, "\x0d\x0aSec-WebSocket-Location: ws://");
}
#else
LWS_CPYAPP(p, "\x0d\x0aSec-WebSocket-Location: ws://");
#endif
LWS_CPYAPP_TOKEN(p, WSI_TOKEN_HOST);
LWS_CPYAPP_TOKEN(p, WSI_TOKEN_GET_URI);
if (wsi->utf8_token[WSI_TOKEN_PROTOCOL].token) {
LWS_CPYAPP(p, "\x0d\x0aSec-WebSocket-Protocol: ");
LWS_CPYAPP_TOKEN(p, WSI_TOKEN_PROTOCOL);
}
LWS_CPYAPP(p, "\x0d\x0a\x0d\x0a");
/* convert the two keys into 32-bit integers */
if (interpret_key(wsi->utf8_token[WSI_TOKEN_KEY1].token, &key1))
goto bail;
if (interpret_key(wsi->utf8_token[WSI_TOKEN_KEY2].token, &key2))
goto bail;
/* lay them out in network byte order (MSB first */
sum[0] = key1 >> 24;
sum[1] = key1 >> 16;
sum[2] = key1 >> 8;
sum[3] = key1;
sum[4] = key2 >> 24;
sum[5] = key2 >> 16;
sum[6] = key2 >> 8;
sum[7] = key2;
/* follow them with the challenge token we were sent */
memcpy(&sum[8], wsi->utf8_token[WSI_TOKEN_CHALLENGE].token, 8);
/*
* compute the md5sum of that 16-byte series and use as our
* payload after our headers
*/
MD5(sum, 16, (unsigned char *)p);
p += 16;
/* it's complete: go ahead and send it */
debug("issuing response packet %d len\n", (int)(p - response));
#ifdef DEBUG
fwrite(response, 1, p - response, stderr);
#endif
n = libwebsocket_write(wsi, (unsigned char *)response,
p - response, LWS_WRITE_HTTP);
if (n < 0) {
fprintf(stderr, "ERROR writing to socket");
goto bail;
}
/* alright clean up and set ourselves into established state */
free(response);
wsi->state = WSI_STATE_ESTABLISHED;
wsi->lws_rx_parse_state = LWS_RXPS_NEW;
/* notify user code that we're ready to roll */
if (wsi->protocol->callback)
wsi->protocol->callback(wsi->protocol->owning_server,
wsi, LWS_CALLBACK_ESTABLISHED,
wsi->user_space, NULL, 0);
return 0;
bail:
return -1;
}
/*
* Perform the newer BASE64-encoded handshake scheme
*/
static int
handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi)
{
static const char *websocket_magic_guid_04 =
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
static const char *websocket_magic_guid_04_masking =
"61AC5F19-FBBA-4540-B96F-6561F1AB40A8";
char accept_buf[MAX_WEBSOCKET_04_KEY_LEN + 37];
char nonce_buf[256];
char mask_summing_buf[256 + MAX_WEBSOCKET_04_KEY_LEN + 37];
unsigned char hash[20];
int n;
char *response;
char *p;
char *m = mask_summing_buf;
int nonce_len = 0;
int accept_len;
char *c;
char ext_name[128];
struct libwebsocket_extension *ext;
int ext_count = 0;
int more = 1;
if (!wsi->utf8_token[WSI_TOKEN_HOST].token_len ||
!wsi->utf8_token[WSI_TOKEN_KEY].token_len) {
debug("handshake_04 missing pieces\n");
/* completed header processing, but missing some bits */
goto bail;
}
if (wsi->utf8_token[WSI_TOKEN_KEY].token_len >=
MAX_WEBSOCKET_04_KEY_LEN) {
fprintf(stderr, "Client sent handshake key longer "
"than max supported %d\n", MAX_WEBSOCKET_04_KEY_LEN);
goto bail;
}
strcpy(accept_buf, wsi->utf8_token[WSI_TOKEN_KEY].token);
strcpy(accept_buf + wsi->utf8_token[WSI_TOKEN_KEY].token_len,
websocket_magic_guid_04);
SHA1((unsigned char *)accept_buf,
wsi->utf8_token[WSI_TOKEN_KEY].token_len +
strlen(websocket_magic_guid_04), hash);
accept_len = lws_b64_encode_string((char *)hash, 20, accept_buf,
sizeof accept_buf);
if (accept_len < 0) {
fprintf(stderr, "Base64 encoded hash too long\n");
goto bail;
}
/* allocate the per-connection user memory (if any) */
if (wsi->protocol->per_session_data_size &&
!libwebsocket_ensure_user_space(wsi))
goto bail;
/* create the response packet */
/* make a buffer big enough for everything */
response = malloc(256 +
wsi->utf8_token[WSI_TOKEN_UPGRADE].token_len +
wsi->utf8_token[WSI_TOKEN_CONNECTION].token_len +
wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len);
if (!response) {
fprintf(stderr, "Out of memory for response buffer\n");
goto bail;
}
p = response;
LWS_CPYAPP(p, "HTTP/1.1 101 Switching Protocols\x0d\x0a"
"Upgrade: WebSocket\x0d\x0a"
"Connection: Upgrade\x0d\x0a"
"Sec-WebSocket-Accept: ");
strcpy(p, accept_buf);
p += accept_len;
if (wsi->ietf_spec_revision == 4) {
LWS_CPYAPP(p, "\x0d\x0aSec-WebSocket-Nonce: ");
/* select the nonce */
n = libwebsockets_get_random(wsi->protocol->owning_server,
hash, 16);
if (n != 16) {
fprintf(stderr, "Unable to read random device %s %d\n",
SYSTEM_RANDOM_FILEPATH, n);
if (wsi->user_space)
free(wsi->user_space);
goto bail;
}
/* encode the nonce */
nonce_len = lws_b64_encode_string((const char *)hash, 16,
nonce_buf, sizeof nonce_buf);
if (nonce_len < 0) {
fprintf(stderr, "Failed to base 64 encode the nonce\n");
if (wsi->user_space)
free(wsi->user_space);
goto bail;
}
/* apply the nonce */
strcpy(p, nonce_buf);
p += nonce_len;
}
if (wsi->utf8_token[WSI_TOKEN_PROTOCOL].token) {
LWS_CPYAPP(p, "\x0d\x0aSec-WebSocket-Protocol: ");
LWS_CPYAPP_TOKEN(p, WSI_TOKEN_PROTOCOL);
}
/*
* Figure out which extensions the client has that we want to
* enable on this connection, and give him back the list
*/
if (wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token_len) {
/*
* break down the list of client extensions
* and go through them
*/
c = wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token;
debug("wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token = %s\n",
wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token);
wsi->count_active_extensions = 0;
n = 0;
while (more) {
if (*c && (*c != ',' && *c != ' ' && *c != '\t')) {
ext_name[n] = *c++;
if (n < sizeof(ext_name) - 1)
n++;
continue;
}
ext_name[n] = '\0';
if (!*c)
more = 0;
else {
c++;
if (!n)
continue;
}
/* check a client's extension against our support */
ext = wsi->protocol->owning_server->extensions;
while (ext && ext->callback) {
if (strcmp(ext_name, ext->name)) {
ext++;
continue;
}
/*
* oh, we do support this one he
* asked for... but let's ask user
* code if it's OK to apply it on this
* particular connection + protocol
*/
n = wsi->protocol->owning_server->
protocols[0].callback(
wsi->protocol->owning_server,
wsi,
LWS_CALLBACK_CONFIRM_EXTENSION_OKAY,
wsi->user_space, ext_name, 0);
/*
* zero return from callback means
* go ahead and allow the extension,
* it's what we get if the callback is
* unhandled
*/
if (n) {
ext++;
continue;
}
/* apply it */
if (ext_count)
*p++ = ',';
else
LWS_CPYAPP(p,
"\x0d\x0aSec-WebSocket-Extensions: ");
p += sprintf(p, "%s", ext_name);
ext_count++;
/* instantiate the extension on this conn */
wsi->active_extensions_user[
wsi->count_active_extensions] =
malloc(ext->per_session_data_size);
memset(wsi->active_extensions_user[
wsi->count_active_extensions], 0,
ext->per_session_data_size);
wsi->active_extensions[
wsi->count_active_extensions] = ext;
/* allow him to construct his context */
ext->callback(wsi->protocol->owning_server,
ext, wsi,
LWS_EXT_CALLBACK_CONSTRUCT,
wsi->active_extensions_user[
wsi->count_active_extensions], NULL, 0);
wsi->count_active_extensions++;
debug("wsi->count_active_extensions <- %d",
wsi->count_active_extensions);
ext++;
}
n = 0;
}
}
/* end of response packet */
LWS_CPYAPP(p, "\x0d\x0a\x0d\x0a");
if (wsi->ietf_spec_revision == 4) {
/*
* precompute the masking key the client will use from the SHA1
* hash of ( base 64 client key we were sent, concatenated with
* the bse 64 nonce we sent, concatenated with a magic constant
* guid specified by the 04 standard )
*
* We store the hash in the connection's wsi ready to use with
* undoing the masking the client has done on framed data it
* sends (we send our data to the client in clear).
*/
strcpy(mask_summing_buf, wsi->utf8_token[WSI_TOKEN_KEY].token);
m += wsi->utf8_token[WSI_TOKEN_KEY].token_len;
strcpy(m, nonce_buf);
m += nonce_len;
strcpy(m, websocket_magic_guid_04_masking);
m += strlen(websocket_magic_guid_04_masking);
SHA1((unsigned char *)mask_summing_buf, m - mask_summing_buf,
wsi->masking_key_04);
}
if (!lws_any_extension_handled(context, wsi,
LWS_EXT_CALLBACK_HANDSHAKE_REPLY_TX,
response, p - response)) {
/* okay send the handshake response accepting the connection */
debug("issuing response packet %d len\n", (int)(p - response));
#ifdef DEBUG
fwrite(response, 1, p - response, stderr);
#endif
n = libwebsocket_write(wsi, (unsigned char *)response,
p - response, LWS_WRITE_HTTP);
if (n < 0) {
fprintf(stderr, "ERROR writing to socket");
goto bail;
}
}
/* alright clean up and set ourselves into established state */
free(response);
wsi->state = WSI_STATE_ESTABLISHED;
wsi->lws_rx_parse_state = LWS_RXPS_NEW;
wsi->rx_packet_length = 0;
/* notify user code that we're ready to roll */
if (wsi->protocol->callback)
wsi->protocol->callback(wsi->protocol->owning_server,
wsi, LWS_CALLBACK_ESTABLISHED,
wsi->user_space, NULL, 0);
return 0;
bail:
return -1;
}
/*
* -04 of the protocol (actually the 80th version) has a radically different
* handshake. The 04 spec gives the following idea
*
* The handshake from the client looks as follows:
*
* GET /chat HTTP/1.1
* Host: server.example.com
* Upgrade: websocket
* Connection: Upgrade
* Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
* Sec-WebSocket-Origin: http://example.com
* Sec-WebSocket-Protocol: chat, superchat
* Sec-WebSocket-Version: 4
*
* The handshake from the server looks as follows:
*
* HTTP/1.1 101 Switching Protocols
* Upgrade: websocket
* Connection: Upgrade
* Sec-WebSocket-Accept: me89jWimTRKTWwrS3aRrL53YZSo=
* Sec-WebSocket-Nonce: AQIDBAUGBwgJCgsMDQ4PEC==
* Sec-WebSocket-Protocol: chat
*/
/*
* We have to take care about parsing because the headers may be split
* into multiple fragments. They may contain unknown headers with arbitrary
* argument lengths. So, we parse using a single-character at a time state
* machine that is completely independent of packet size.
*/
int
libwebsocket_read(struct libwebsocket_context *context,
struct libwebsocket *wsi, unsigned char * buf, size_t len)
{
size_t n;
switch (wsi->state) {
case WSI_STATE_HTTP:
wsi->state = WSI_STATE_HTTP_HEADERS;
wsi->parser_state = WSI_TOKEN_NAME_PART;
/* fallthru */
case WSI_STATE_HTTP_HEADERS:
debug("issuing %d bytes to parser\n", (int)len);
#ifdef DEBUG
fwrite(buf, 1, len, stderr);
#endif
switch (wsi->mode) {
case LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY:
case LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE:
case LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY:
case LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT:
case LWS_CONNMODE_WS_CLIENT:
for (n = 0; n < len; n++)
libwebsocket_client_rx_sm(wsi, *buf++);
return 0;
default:
break;
}
/* LWS_CONNMODE_WS_SERVING */
for (n = 0; n < len; n++)
libwebsocket_parse(wsi, *buf++);
if (wsi->parser_state != WSI_PARSING_COMPLETE)
break;
debug("seem to be serving, mode is %d\n", wsi->mode);
debug("libwebsocket_parse sees parsing complete\n");
/* is this websocket protocol or normal http 1.0? */
if (!wsi->utf8_token[WSI_TOKEN_UPGRADE].token_len ||
!wsi->utf8_token[WSI_TOKEN_CONNECTION].token_len) {
wsi->state = WSI_STATE_HTTP;
if (wsi->protocol->callback)
(wsi->protocol->callback)(context, wsi,
LWS_CALLBACK_HTTP, wsi->user_space,
wsi->utf8_token[WSI_TOKEN_GET_URI].token, 0);
return 0;
}
if (!wsi->protocol)
fprintf(stderr, "NULL protocol at libwebsocket_read\n");
/*
* It's websocket
*
* Make sure user side is happy about protocol
*/
while (wsi->protocol->callback) {
if (wsi->utf8_token[WSI_TOKEN_PROTOCOL].token == NULL) {
if (wsi->protocol->name == NULL)
break;
} else
if (wsi->protocol->name && strcmp(
wsi->utf8_token[WSI_TOKEN_PROTOCOL].token,
wsi->protocol->name) == 0)
break;
wsi->protocol++;
}
/* we didn't find a protocol he wanted? */
if (wsi->protocol->callback == NULL) {
if (wsi->utf8_token[WSI_TOKEN_PROTOCOL].token == NULL)
fprintf(stderr, "[no protocol] "
"not supported (use NULL .name)\n");
else
fprintf(stderr, "Requested protocol %s "
"not supported\n",
wsi->utf8_token[WSI_TOKEN_PROTOCOL].token);
goto bail;
}
/*
* find out which spec version the client is using
* if this header is not given, we default to 00 (aka 76)
*/
if (wsi->utf8_token[WSI_TOKEN_VERSION].token_len)
wsi->ietf_spec_revision =
atoi(wsi->utf8_token[WSI_TOKEN_VERSION].token);
/*
* Give the user code a chance to study the request and
* have the opportunity to deny it
*/
if ((wsi->protocol->callback)(wsi->protocol->owning_server, wsi,
LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
&wsi->utf8_token[0], NULL, 0)) {
fprintf(stderr, "User code denied connection\n");
goto bail;
}
/*
* Perform the handshake according to the protocol version the
* client announced
*/
switch (wsi->ietf_spec_revision) {
case 0: /* applies to 76 and 00 */
wsi->xor_mask = xor_no_mask;
if (handshake_00(context, wsi))
goto bail;
break;
case 4: /* 04 */
wsi->xor_mask = xor_mask_04;
debug("libwebsocket_parse calling handshake_04\n");
if (handshake_0405(context, wsi))
goto bail;
break;
case 5:
case 6:
case 7:
case 8:
case 13:
wsi->xor_mask = xor_mask_05;
debug("libwebsocket_parse calling handshake_04\n");
if (handshake_0405(context, wsi))
goto bail;
break;
default:
fprintf(stderr, "Unknown client spec version %d\n",
wsi->ietf_spec_revision);
goto bail;
}
debug("accepted v%02d connection\n",
wsi->ietf_spec_revision);
break;
case WSI_STATE_AWAITING_CLOSE_ACK:
case WSI_STATE_ESTABLISHED:
switch (wsi->mode) {
case LWS_CONNMODE_WS_CLIENT:
for (n = 0; n < len; n++)
if (libwebsocket_client_rx_sm(wsi, *buf++) < 0)
goto bail;
return 0;
default:
break;
}
/* LWS_CONNMODE_WS_SERVING */
if (libwebsocket_interpret_incoming_packet(wsi, buf, len) < 0)
goto bail;
break;
default:
break;
}
return 0;
bail:
libwebsocket_close_and_free_session(context, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
return -1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,731 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#ifndef __LIBWEBSOCKET_H__
#define __LIBWEBSOCKET_H__
#ifdef __cplusplus
extern "C" {
#include <cstddef>
#endif
#ifdef WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stddef.h>
#include "../win32port/win32helpers/websock-w32.h"
#include "../win32port/win32helpers/gettimeofday.h"
#define strcasecmp stricmp
typedef int ssize_t;
#ifdef LWS_DLL
#ifdef LWS_INTERNAL
#define LWS_EXTERN extern __declspec(dllexport)
#else
#define LWS_EXTERN extern __declspec(dllimport)
#endif
#endif
#else
#include <poll.h>
#endif
#ifndef LWS_EXTERN
#define LWS_EXTERN extern
#endif
#define CONTEXT_PORT_NO_LISTEN 0
#define MAX_MUX_RECURSION 2
enum libwebsocket_context_options {
LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK = 1,
LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = 2,
};
enum libwebsocket_callback_reasons {
LWS_CALLBACK_ESTABLISHED,
LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
LWS_CALLBACK_CLIENT_ESTABLISHED,
LWS_CALLBACK_CLOSED,
LWS_CALLBACK_RECEIVE,
LWS_CALLBACK_CLIENT_RECEIVE,
LWS_CALLBACK_CLIENT_RECEIVE_PONG,
LWS_CALLBACK_CLIENT_WRITEABLE,
LWS_CALLBACK_SERVER_WRITEABLE,
LWS_CALLBACK_HTTP,
LWS_CALLBACK_BROADCAST,
LWS_CALLBACK_FILTER_NETWORK_CONNECTION,
LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,
LWS_CALLBACK_CONFIRM_EXTENSION_OKAY,
LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED,
/* external poll() management support */
LWS_CALLBACK_ADD_POLL_FD,
LWS_CALLBACK_DEL_POLL_FD,
LWS_CALLBACK_SET_MODE_POLL_FD,
LWS_CALLBACK_CLEAR_MODE_POLL_FD,
};
enum libwebsocket_extension_callback_reasons {
LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT,
LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT,
LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT,
LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT,
LWS_EXT_CALLBACK_CONSTRUCT,
LWS_EXT_CALLBACK_CLIENT_CONSTRUCT,
LWS_EXT_CALLBACK_CHECK_OK_TO_REALLY_CLOSE,
LWS_EXT_CALLBACK_CHECK_OK_TO_PROPOSE_EXTENSION,
LWS_EXT_CALLBACK_DESTROY,
LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING,
LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED,
LWS_EXT_CALLBACK_PACKET_RX_PREPARSE,
LWS_EXT_CALLBACK_PACKET_TX_PRESEND,
LWS_EXT_CALLBACK_PACKET_TX_DO_SEND,
LWS_EXT_CALLBACK_HANDSHAKE_REPLY_TX,
LWS_EXT_CALLBACK_FLUSH_PENDING_TX,
LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX,
LWS_EXT_CALLBACK_CAN_PROXY_CLIENT_CONNECTION,
LWS_EXT_CALLBACK_1HZ,
LWS_EXT_CALLBACK_REQUEST_ON_WRITEABLE,
LWS_EXT_CALLBACK_IS_WRITEABLE,
};
enum libwebsocket_write_protocol {
LWS_WRITE_TEXT,
LWS_WRITE_BINARY,
LWS_WRITE_CONTINUATION,
LWS_WRITE_HTTP,
/* special 04+ opcodes */
LWS_WRITE_CLOSE,
LWS_WRITE_PING,
LWS_WRITE_PONG,
/* flags */
LWS_WRITE_NO_FIN = 0x40,
/*
* client packet payload goes out on wire unmunged
* only useful for security tests since normal servers cannot
* decode the content if used
*/
LWS_WRITE_CLIENT_IGNORE_XOR_MASK = 0x80
};
/*
* you need these to look at headers that have been parsed if using the
* LWS_CALLBACK_FILTER_CONNECTION callback. If a header from the enum
* list below is absent, .token = NULL and token_len = 0. Otherwise .token
* points to .token_len chars containing that header content.
*/
struct lws_tokens {
char *token;
int token_len;
};
enum lws_token_indexes {
WSI_TOKEN_GET_URI,
WSI_TOKEN_HOST,
WSI_TOKEN_CONNECTION,
WSI_TOKEN_KEY1,
WSI_TOKEN_KEY2,
WSI_TOKEN_PROTOCOL,
WSI_TOKEN_UPGRADE,
WSI_TOKEN_ORIGIN,
WSI_TOKEN_DRAFT,
WSI_TOKEN_CHALLENGE,
/* new for 04 */
WSI_TOKEN_KEY,
WSI_TOKEN_VERSION,
WSI_TOKEN_SWORIGIN,
/* new for 05 */
WSI_TOKEN_EXTENSIONS,
/* client receives these */
WSI_TOKEN_ACCEPT,
WSI_TOKEN_NONCE,
WSI_TOKEN_HTTP,
WSI_TOKEN_MUXURL,
/* always last real token index*/
WSI_TOKEN_COUNT,
/* parser state additions */
WSI_TOKEN_NAME_PART,
WSI_TOKEN_SKIPPING,
WSI_TOKEN_SKIPPING_SAW_CR,
WSI_PARSING_COMPLETE,
WSI_INIT_TOKEN_MUXURL,
};
/*
* From 06 spec
1000
1000 indicates a normal closure, meaning whatever purpose the
connection was established for has been fulfilled.
1001
1001 indicates that an endpoint is "going away", such as a server
going down, or a browser having navigated away from a page.
1002
1002 indicates that an endpoint is terminating the connection due
to a protocol error.
1003
1003 indicates that an endpoint is terminating the connection
because it has received a type of data it cannot accept (e.g. an
endpoint that understands only text data may send this if it
receives a binary message.)
1004
1004 indicates that an endpoint is terminating the connection
because it has received a message that is too large.
*/
enum lws_close_status {
LWS_CLOSE_STATUS_NOSTATUS = 0,
LWS_CLOSE_STATUS_NORMAL = 1000,
LWS_CLOSE_STATUS_GOINGAWAY = 1001,
LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002,
LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003,
LWS_CLOSE_STATUS_PAYLOAD_TOO_LARGE = 1004,
};
struct libwebsocket;
struct libwebsocket_context;
struct libwebsocket_extension;
/**
* callback_function() - User server actions
* @context: Websockets context
* @wsi: Opaque websocket instance pointer
* @reason: The reason for the call
* @user: Pointer to per-session user data allocated by library
* @in: Pointer used for some callback reasons
* @len: Length set for some callback reasons
*
* This callback is the way the user controls what is served. All the
* protocol detail is hidden and handled by the library.
*
* For each connection / session there is user data allocated that is
* pointed to by "user". You set the size of this user data area when
* the library is initialized with libwebsocket_create_server.
*
* You get an opportunity to initialize user data when called back with
* LWS_CALLBACK_ESTABLISHED reason.
*
* LWS_CALLBACK_ESTABLISHED: after the server completes a handshake with
* an incoming client
*
* LWS_CALLBACK_CLIENT_CONNECTION_ERROR: the request client connection has
* been unable to complete a handshake with the remote server
*
* LWS_CALLBACK_CLIENT_ESTABLISHED: after your client connection completed
* a handshake with the remote server
*
* LWS_CALLBACK_CLOSED: when the websocket session ends
*
* LWS_CALLBACK_BROADCAST: signal to send to client (you would use
* libwebsocket_write() taking care about the
* special buffer requirements
*
* LWS_CALLBACK_RECEIVE: data has appeared for this server endpoint from a
* remote client, it can be found at *in and is
* len bytes long
*
* LWS_CALLBACK_CLIENT_RECEIVE_PONG: if you elected to see PONG packets,
* they appear with this callback reason. PONG
* packets only exist in 04+ protocol
*
* LWS_CALLBACK_CLIENT_RECEIVE: data has appeared from the server for the
* client connection, it can be found at *in and
* is len bytes long
*
* LWS_CALLBACK_HTTP: an http request has come from a client that is not
* asking to upgrade the connection to a websocket
* one. This is a chance to serve http content,
* for example, to send a script to the client
* which will then open the websockets connection.
* @in points to the URI path requested and
* libwebsockets_serve_http_file() makes it very
* simple to send back a file to the client.
*
* LWS_CALLBACK_CLIENT_WRITEABLE:
* LWS_CALLBACK_SERVER_WRITEABLE: If you call
* libwebsocket_callback_on_writable() on a connection, you will
* get one of these callbacks coming when the connection socket
* is able to accept another write packet without blocking.
* If it already was able to take another packet without blocking,
* you'll get this callback at the next call to the service loop
* function. Notice that CLIENTs get LWS_CALLBACK_CLIENT_WRITEABLE
* and servers get LWS_CALLBACK_SERVER_WRITEABLE.
*
* LWS_CALLBACK_FILTER_NETWORK_CONNECTION: called when a client connects to
* the server at network level; the connection is accepted but then
* passed to this callback to decide whether to hang up immediately
* or not, based on the client IP. @user contains the connection
* socket's descriptor. Return non-zero to terminate
* the connection before sending or receiving anything.
* Because this happens immediately after the network connection
* from the client, there's no websocket protocol selected yet so
* this callback is issued only to protocol 0.
*
* LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: called when the handshake has
* been received and parsed from the client, but the response is
* not sent yet. Return non-zero to disallow the connection.
* @user is a pointer to an array of struct lws_tokens, you can
* use the header enums lws_token_indexes from libwebsockets.h
* to check for and read the supported header presence and
* content before deciding to allow the handshake to proceed or
* to kill the connection.
*
* LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: if configured for
* including OpenSSL support, this callback allows your user code
* to perform extra SSL_CTX_load_verify_locations() or similar
* calls to direct OpenSSL where to find certificates the client
* can use to confirm the remote server identity. @user is the
* OpenSSL SSL_CTX*
*
* LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS: if configured for
* including OpenSSL support, this callback allows your user code
* to load extra certifcates into the server which allow it to
* verify the validity of certificates returned by clients. @user
* is the server's OpenSSL SSL_CTX*
*
* LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION: if the
* libwebsockets context was created with the option
* LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT, then this
* callback is generated during OpenSSL verification of the cert
* sent from the client. It is sent to protocol[0] callback as
* no protocol has been negotiated on the connection yet.
* Notice that the libwebsockets context and wsi are both NULL
* during this callback. See
* http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html
* to understand more detail about the OpenSSL callback that
* generates this libwebsockets callback and the meanings of the
* arguments passed. In this callback, @user is the x509_ctx,
* @in is the ssl pointer and @len is preverify_ok
* Notice that this callback maintains libwebsocket return
* conventions, return 0 to mean the cert is OK or 1 to fail it.
* This also means that if you don't handle this callback then
* the default callback action of returning 0 allows the client
* certificates.
*
* LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER: this callback happens
* when a client handshake is being compiled. @user is NULL,
* @in is a char **, it's pointing to a char * which holds the
* next location in the header buffer where you can add
* headers, and @len is the remaining space in the header buffer,
* which is typically some hundreds of bytes. So, to add a canned
* cookie, your handler code might look similar to:
*
* char **p = (char **)in;
*
* if (len < 100)
* return 1;
*
* *p += sprintf(*p, "Cookie: a=b\x0d\x0a");
*
* return 0;
*
* Notice if you add anything, you just have to take care about
* the CRLF on the line you added. Obviously this callback is
* optional, if you don't handle it everything is fine.
*
* Notice the callback is coming to protocols[0] all the time,
* because there is no specific protocol handshook yet.
*
* LWS_CALLBACK_CONFIRM_EXTENSION_OKAY: When the server handshake code
* sees that it does support a requested extension, before
* accepting the extension by additing to the list sent back to
* the client it gives this callback just to check that it's okay
* to use that extension. It calls back to the requested protocol
* and with @in being the extension name, @len is 0 and @user is
* valid. Note though at this time the ESTABLISHED callback hasn't
* happened yet so if you initialize @user content there, @user
* content during this callback might not be useful for anything.
* Notice this callback comes to protocols[0].
*
* LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED: When a client
* connection is being prepared to start a handshake to a server,
* each supported extension is checked with protocols[0] callback
* with this reason, giving the user code a chance to suppress the
* claim to support that extension by returning non-zero. If
* unhandled, by default 0 will be returned and the extension
* support included in the header to the server. Notice this
* callback comes to protocols[0].
*
* The next four reasons are optional and only need taking care of if you
* will be integrating libwebsockets sockets into an external polling
* array.
*
* LWS_CALLBACK_ADD_POLL_FD: libwebsocket deals with its poll() loop
* internally, but in the case you are integrating with another
* server you will need to have libwebsocket sockets share a
* polling array with the other server. This and the other
* POLL_FD related callbacks let you put your specialized
* poll array interface code in the callback for protocol 0, the
* first protocol you support, usually the HTTP protocol in the
* serving case. This callback happens when a socket needs to be
* added to the polling loop: @user contains the fd, and
* @len is the events bitmap (like, POLLIN). If you are using the
* internal polling loop (the "service" callback), you can just
* ignore these callbacks.
*
* LWS_CALLBACK_DEL_POLL_FD: This callback happens when a socket descriptor
* needs to be removed from an external polling array. @user is
* the socket desricptor. If you are using the internal polling
* loop, you can just ignore it.
*
* LWS_CALLBACK_SET_MODE_POLL_FD: This callback happens when libwebsockets
* wants to modify the events for the socket descriptor in @user.
* The handler should OR @len on to the events member of the pollfd
* struct for this socket descriptor. If you are using the
* internal polling loop, you can just ignore it.
*
* LWS_CALLBACK_CLEAR_MODE_POLL_FD: This callback occurs when libwebsockets
* wants to modify the events for the socket descriptor in @user.
* The handler should AND ~@len on to the events member of the
* pollfd struct for this socket descriptor. If you are using the
* internal polling loop, you can just ignore it.
*/
LWS_EXTERN int callback(struct libwebsocket_context * context,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason, void *user,
void *in, size_t len);
typedef int (callback_function)(struct libwebsocket_context * context,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason, void *user,
void *in, size_t len);
/**
* extension_callback_function() - Hooks to allow extensions to operate
* @context: Websockets context
* @ext: This extension
* @wsi: Opaque websocket instance pointer
* @reason: The reason for the call
* @user: Pointer to per-session user data allocated by library
* @in: Pointer used for some callback reasons
* @len: Length set for some callback reasons
*
* Each extension that is active on a particular connection receives
* callbacks during the connection lifetime to allow the extension to
* operate on websocket data and manage itself.
*
* Libwebsockets takes care of allocating and freeing "user" memory for
* each active extension on each connection. That is what is pointed to
* by the @user parameter.
*
* LWS_EXT_CALLBACK_CONSTRUCT: called when the server has decided to
* select this extension from the list provided by the client,
* just before the server will send back the handshake accepting
* the connection with this extension active. This gives the
* extension a chance to initialize its connection context found
* in @user.
*
* LWS_EXT_CALLBACK_CLIENT_CONSTRUCT: same as LWS_EXT_CALLBACK_CONSTRUCT
* but called when client is instantiating this extension. Some
* extensions will work the same on client and server side and then
* you can just merge handlers for both CONSTRUCTS.
*
* LWS_EXT_CALLBACK_DESTROY: called when the connection the extension was
* being used on is about to be closed and deallocated. It's the
* last chance for the extension to deallocate anything it has
* allocated in the user data (pointed to by @user) before the
* user data is deleted. This same callback is used whether you
* are in client or server instantiation context.
*
* LWS_EXT_CALLBACK_PACKET_RX_PREPARSE: when this extension was active on
* a connection, and a packet of data arrived at the connection,
* it is passed to this callback to give the extension a chance to
* change the data, eg, decompress it. @user is pointing to the
* extension's private connection context data, @in is pointing
* to an lws_tokens struct, it consists of a char * pointer called
* token, and an int called token_len. At entry, these are
* set to point to the received buffer and set to the content
* length. If the extension will grow the content, it should use
* a new buffer allocated in its private user context data and
* set the pointed-to lws_tokens members to point to its buffer.
*
* LWS_EXT_CALLBACK_PACKET_TX_PRESEND: this works the same way as
* LWS_EXT_CALLBACK_PACKET_RX_PREPARSE above, except it gives the
* extension a chance to change websocket data just before it will
* be sent out. Using the same lws_token pointer scheme in @in,
* the extension can change the buffer and the length to be
* transmitted how it likes. Again if it wants to grow the
* buffer safely, it should copy the data into its own buffer and
* set the lws_tokens token pointer to it.
*/
LWS_EXTERN int extension_callback(struct libwebsocket_context * context,
struct libwebsocket_extension *ext,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons reason, void *user,
void *in, size_t len);
typedef int (extension_callback_function)(struct libwebsocket_context * context,
struct libwebsocket_extension *ext,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons reason, void *user,
void *in, size_t len);
/**
* struct libwebsocket_protocols - List of protocols and handlers server
* supports.
* @name: Protocol name that must match the one given in the client
* Javascript new WebSocket(url, 'protocol') name
* @callback: The service callback used for this protocol. It allows the
* service action for an entire protocol to be encapsulated in
* the protocol-specific callback
* @per_session_data_size: Each new connection using this protocol gets
* this much memory allocated on connection establishment and
* freed on connection takedown. A pointer to this per-connection
* allocation is passed into the callback in the 'user' parameter
* @owning_server: the server init call fills in this opaque pointer when
* registering this protocol with the server.
* @broadcast_socket_port: the server init call fills this in with the
* localhost port number used to forward broadcasts for this
* protocol
* @broadcast_socket_user_fd: the server init call fills this in ... the main()
* process context can write to this socket to perform broadcasts
* (use the libwebsockets_broadcast() api to do this instead,
* it works from any process context)
* @protocol_index: which protocol we are starting from zero
*
* This structure represents one protocol supported by the server. An
* array of these structures is passed to libwebsocket_create_server()
* allows as many protocols as you like to be handled by one server.
*/
struct libwebsocket_protocols {
const char *name;
callback_function *callback;
size_t per_session_data_size;
/*
* below are filled in on server init and can be left uninitialized,
* no need for user to use them directly either
*/
struct libwebsocket_context *owning_server;
int broadcast_socket_port;
int broadcast_socket_user_fd;
int protocol_index;
};
/**
* struct libwebsocket_extension - An extension we know how to cope with
*
* @name: Formal extension name, eg, "deflate-stream"
* @callback: Service callback
* @per_session_data_size: Libwebsockets will auto-malloc this much
* memory for the use of the extension, a pointer
* to it comes in the @user callback parameter
* @per_context_private_data: Optional storage for this externsion that
* is per-context, so it can track stuff across
* all sessions, etc, if it wants
*/
struct libwebsocket_extension {
const char *name;
extension_callback_function *callback;
size_t per_session_data_size;
void * per_context_private_data;
};
LWS_EXTERN struct libwebsocket_context *
libwebsocket_create_context(int port, const char * interf,
struct libwebsocket_protocols *protocols,
struct libwebsocket_extension *extensions,
const char *ssl_cert_filepath,
const char *ssl_private_key_filepath, int gid, int uid,
unsigned int options);
LWS_EXTERN void
libwebsocket_context_destroy(struct libwebsocket_context *context);
LWS_EXTERN int
libwebsockets_fork_service_loop(struct libwebsocket_context *context);
LWS_EXTERN int
libwebsocket_service(struct libwebsocket_context *context, int timeout_ms);
LWS_EXTERN int
libwebsocket_service_fd(struct libwebsocket_context *context,
struct pollfd *pollfd);
/*
* IMPORTANT NOTICE!
*
* When sending with websocket protocol (LWS_WRITE_TEXT or LWS_WRITE_BINARY)
* the send buffer has to have LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE
* buf, and LWS_SEND_BUFFER_POST_PADDING bytes valid AFTER (buf + len).
*
* This allows us to add protocol info before and after the data, and send as
* one packet on the network without payload copying, for maximum efficiency.
*
* So for example you need this kind of code to use libwebsocket_write with a
* 128-byte payload
*
* char buf[LWS_SEND_BUFFER_PRE_PADDING + 128 + LWS_SEND_BUFFER_POST_PADDING];
*
* // fill your part of the buffer... for example here it's all zeros
* memset(&buf[LWS_SEND_BUFFER_PRE_PADDING], 0, 128);
*
* libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 128);
*
* When sending LWS_WRITE_HTTP, there is no protocol addition and you can just
* use the whole buffer without taking care of the above.
*/
/*
* this is the frame nonce plus two header plus 8 length
* there's an additional two for mux extension per mux nesting level
* 2 byte prepend on close will already fit because control frames cannot use
* the big length style
*/
#define LWS_SEND_BUFFER_PRE_PADDING (4 + 10 + (2 * MAX_MUX_RECURSION))
#define LWS_SEND_BUFFER_POST_PADDING 1
LWS_EXTERN int
libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, size_t len,
enum libwebsocket_write_protocol protocol);
LWS_EXTERN int
libwebsockets_serve_http_file(struct libwebsocket *wsi, const char *file,
const char *content_type);
/* notice - you need the pre- and post- padding allocation for buf below */
LWS_EXTERN int
libwebsockets_broadcast(const struct libwebsocket_protocols *protocol,
unsigned char *buf, size_t len);
LWS_EXTERN const struct libwebsocket_protocols *
libwebsockets_get_protocol(struct libwebsocket *wsi);
LWS_EXTERN int
libwebsocket_callback_on_writable(struct libwebsocket_context *context,
struct libwebsocket *wsi);
LWS_EXTERN int
libwebsocket_callback_on_writable_all_protocol(
const struct libwebsocket_protocols *protocol);
LWS_EXTERN int
libwebsocket_get_socket_fd(struct libwebsocket *wsi);
LWS_EXTERN int
libwebsocket_is_final_fragment(struct libwebsocket *wsi);
LWS_EXTERN void *
libwebsocket_ensure_user_space(struct libwebsocket *wsi);
LWS_EXTERN int
libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable);
LWS_EXTERN size_t
libwebsockets_remaining_packet_payload(struct libwebsocket *wsi);
LWS_EXTERN struct libwebsocket *
libwebsocket_client_connect(struct libwebsocket_context *clients,
const char *address,
int port,
int ssl_connection,
const char *path,
const char *host,
const char *origin,
const char *protocol,
int ietf_version_or_minus_one);
LWS_EXTERN struct libwebsocket *
libwebsocket_client_connect_extended(struct libwebsocket_context *clients,
const char *address,
int port,
int ssl_connection,
const char *path,
const char *host,
const char *origin,
const char *protocol,
int ietf_version_or_minus_one,
void *userdata);
LWS_EXTERN const char *
libwebsocket_canonical_hostname(struct libwebsocket_context *context);
LWS_EXTERN void
libwebsockets_get_peer_addresses(int fd, char *name, int name_len,
char *rip, int rip_len);
LWS_EXTERN void
libwebsockets_hangup_on_client(struct libwebsocket_context *context, int fd);
LWS_EXTERN void
libwebsocket_close_and_free_session(struct libwebsocket_context *context,
struct libwebsocket *wsi, enum lws_close_status);
LWS_EXTERN int
libwebsockets_get_random(struct libwebsocket_context *context,
void *buf, int len);
LWS_EXTERN int
lws_send_pipe_choked(struct libwebsocket *wsi);
LWS_EXTERN unsigned char *
libwebsockets_SHA1(const unsigned char *d, size_t n, unsigned char *md);
LWS_EXTERN int
lws_b64_encode_string(const char *in, int in_len, char *out, int out_size);
LWS_EXTERN int
lws_b64_decode_string(const char *in, char *out, int out_size);
LWS_EXTERN struct libwebsocket_extension libwebsocket_internal_extensions[];
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,217 @@
/*
* Modified from Polarssl here
* http://polarssl.org/show_source?file=md5
* under GPL2 or later
*/
#include <string.h>
#include <stdio.h>
#define GET_ULONG_LE(n, b, i) \
{ \
(n) = ((unsigned long)(b)[i]) \
| ((unsigned long)(b)[(i) + 1] << 8) \
| ((unsigned long)(b)[(i) + 2] << 16) \
| ((unsigned long)(b)[(i) + 3] << 24); \
}
#define PUT_ULONG_LE(n, b, i) \
{ \
(b)[i] = (unsigned char)(n); \
(b)[(i) + 1] = (unsigned char)((n) >> 8); \
(b)[(i) + 2] = (unsigned char)((n) >> 16); \
(b)[(i) + 3] = (unsigned char)((n) >> 24); \
}
static const unsigned char md5_padding[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
static const unsigned long state_init[] = {
0, 0, 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476
};
static void
md5_process(unsigned long *state, const unsigned char *data)
{
unsigned long X[16], A, B, C, D;
int v;
for (v = 0; v < 16; v++)
GET_ULONG_LE(X[v], data, v << 2);
#define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define P(a, b, c, d, k, s, t) { a += F(b, c, d) + X[k] + t; a = S(a, s) + b; }
A = state[0];
B = state[1];
C = state[2];
D = state[3];
#define F(x, y, z) (z ^ (x & (y ^ z)))
P(A, B, C, D, 0, 7, 0xD76AA478);
P(D, A, B, C, 1, 12, 0xE8C7B756);
P(C, D, A, B, 2, 17, 0x242070DB);
P(B, C, D, A, 3, 22, 0xC1BDCEEE);
P(A, B, C, D, 4, 7, 0xF57C0FAF);
P(D, A, B, C, 5, 12, 0x4787C62A);
P(C, D, A, B, 6, 17, 0xA8304613);
P(B, C, D, A, 7, 22, 0xFD469501);
P(A, B, C, D, 8, 7, 0x698098D8);
P(D, A, B, C, 9, 12, 0x8B44F7AF);
P(C, D, A, B, 10, 17, 0xFFFF5BB1);
P(B, C, D, A, 11, 22, 0x895CD7BE);
P(A, B, C, D, 12, 7, 0x6B901122);
P(D, A, B, C, 13, 12, 0xFD987193);
P(C, D, A, B, 14, 17, 0xA679438E);
P(B, C, D, A, 15, 22, 0x49B40821);
#undef F
#define F(x, y, z) (y ^ (z & (x ^ y)))
P(A, B, C, D, 1, 5, 0xF61E2562);
P(D, A, B, C, 6, 9, 0xC040B340);
P(C, D, A, B, 11, 14, 0x265E5A51);
P(B, C, D, A, 0, 20, 0xE9B6C7AA);
P(A, B, C, D, 5, 5, 0xD62F105D);
P(D, A, B, C, 10, 9, 0x02441453);
P(C, D, A, B, 15, 14, 0xD8A1E681);
P(B, C, D, A, 4, 20, 0xE7D3FBC8);
P(A, B, C, D, 9, 5, 0x21E1CDE6);
P(D, A, B, C, 14, 9, 0xC33707D6);
P(C, D, A, B, 3, 14, 0xF4D50D87);
P(B, C, D, A, 8, 20, 0x455A14ED);
P(A, B, C, D, 13, 5, 0xA9E3E905);
P(D, A, B, C, 2, 9, 0xFCEFA3F8);
P(C, D, A, B, 7, 14, 0x676F02D9);
P(B, C, D, A, 12, 20, 0x8D2A4C8A);
#undef F
#define F(x, y, z) (x ^ y ^ z)
P(A, B, C, D, 5, 4, 0xFFFA3942);
P(D, A, B, C, 8, 11, 0x8771F681);
P(C, D, A, B, 11, 16, 0x6D9D6122);
P(B, C, D, A, 14, 23, 0xFDE5380C);
P(A, B, C, D, 1, 4, 0xA4BEEA44);
P(D, A, B, C, 4, 11, 0x4BDECFA9);
P(C, D, A, B, 7, 16, 0xF6BB4B60);
P(B, C, D, A, 10, 23, 0xBEBFBC70);
P(A, B, C, D, 13, 4, 0x289B7EC6);
P(D, A, B, C, 0, 11, 0xEAA127FA);
P(C, D, A, B, 3, 16, 0xD4EF3085);
P(B, C, D, A, 6, 23, 0x04881D05);
P(A, B, C, D, 9, 4, 0xD9D4D039);
P(D, A, B, C, 12, 11, 0xE6DB99E5);
P(C, D, A, B, 15, 16, 0x1FA27CF8);
P(B, C, D, A, 2, 23, 0xC4AC5665);
#undef F
#define F(x, y, z) (y ^ (x | ~z))
P(A, B, C, D, 0, 6, 0xF4292244);
P(D, A, B, C, 7, 10, 0x432AFF97);
P(C, D, A, B, 14, 15, 0xAB9423A7);
P(B, C, D, A, 5, 21, 0xFC93A039);
P(A, B, C, D, 12, 6, 0x655B59C3);
P(D, A, B, C, 3, 10, 0x8F0CCC92);
P(C, D, A, B, 10, 15, 0xFFEFF47D);
P(B, C, D, A, 1, 21, 0x85845DD1);
P(A, B, C, D, 8, 6, 0x6FA87E4F);
P(D, A, B, C, 15, 10, 0xFE2CE6E0);
P(C, D, A, B, 6, 15, 0xA3014314);
P(B, C, D, A, 13, 21, 0x4E0811A1);
P(A, B, C, D, 4, 6, 0xF7537E82);
P(D, A, B, C, 11, 10, 0xBD3AF235);
P(C, D, A, B, 2, 15, 0x2AD7D2BB);
P(B, C, D, A, 9, 21, 0xEB86D391);
#undef F
state[0] += A;
state[1] += B;
state[2] += C;
state[3] += D;
}
static
void md5_update(unsigned long *state, unsigned char *buffer,
const unsigned char *input, int ilen)
{
int fill;
unsigned long left;
if (ilen <= 0)
return;
left = state[0] & 0x3F;
fill = 64 - left;
state[0] += ilen;
state[0] &= 0xFFFFFFFF;
if (state[0] < (unsigned long)ilen)
state[1]++;
if (left && ilen >= fill) {
memcpy(buffer + left, input, fill);
md5_process(&state[2], buffer);
input += fill;
ilen -= fill;
left = 0;
}
while (ilen >= 64) {
md5_process(&state[2], input);
input += 64;
ilen -= 64;
}
if (ilen > 0)
memcpy(buffer + left, input, ilen);
}
void
MD5(const unsigned char *input, int ilen, unsigned char *output)
{
unsigned long last, padn;
unsigned long high, low;
unsigned char msglen[8];
unsigned long state[6];
unsigned char buffer[64];
memcpy(&state[0], &state_init[0], sizeof(state_init));
md5_update(state, buffer, input, ilen);
high = (state[0] >> 29) | (state[1] << 3);
low = state[0] << 3;
PUT_ULONG_LE(low, msglen, 0);
PUT_ULONG_LE(high, msglen, 4);
last = state[0] & 0x3F;
padn = (last < 56) ? (56 - last) : (120 - last);
md5_update(state, buffer, md5_padding, padn);
md5_update(state, buffer, msglen, 8);
PUT_ULONG_LE(state[2], output, 0);
PUT_ULONG_LE(state[3], output, 4);
PUT_ULONG_LE(state[4], output, 8);
PUT_ULONG_LE(state[5], output, 12);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,445 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#ifdef __MINGW64__
#else
#ifdef __MINGW32__
#else
#include <netdb.h>
#endif
#endif
#include <stdarg.h>
#include <sys/stat.h>
#ifdef WIN32
#ifdef __MINGW64__
#else
#ifdef __MINGW32__
#else
#include <time.h >
#endif
#endif
#include <winsock2.h>
#include <ws2ipdef.h>
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#ifndef LWS_NO_FORK
#ifdef HAVE_SYS_PRCTL_H
#include <sys/prctl.h>
#endif
#endif
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <poll.h>
#include <sys/mman.h>
#include <sys/time.h>
#endif
#ifdef LWS_OPENSSL_SUPPORT
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
#endif
#include "libwebsockets.h"
#if 0
#define DEBUG
#endif
#ifdef DEBUG
#ifdef WIN32
static
#else
static inline
#endif
void debug(const char *format, ...)
{
va_list ap;
va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap);
}
#else
#ifdef WIN32
static
#else
static inline
#endif
void debug(const char *format, ...)
{
}
#endif
/*
* Mac OSX as well as iOS do not define the MSG_NOSIGNAL flag,
* but happily have something equivalent in the SO_NOSIGPIPE flag.
*/
#ifdef __APPLE__
#define MSG_NOSIGNAL SO_NOSIGPIPE
#endif
#define FD_HASHTABLE_MODULUS 32
#define MAX_CLIENTS 100
#define LWS_MAX_HEADER_NAME_LENGTH 64
#define LWS_MAX_HEADER_LEN 4096
#define LWS_INITIAL_HDR_ALLOC 256
#define LWS_ADDITIONAL_HDR_ALLOC 64
#define MAX_USER_RX_BUFFER 4096
#define MAX_BROADCAST_PAYLOAD 2048
#define LWS_MAX_PROTOCOLS 10
#define LWS_MAX_EXTENSIONS_ACTIVE 10
#define SPEC_LATEST_SUPPORTED 13
#define MAX_WEBSOCKET_04_KEY_LEN 128
#define SYSTEM_RANDOM_FILEPATH "/dev/urandom"
enum lws_websocket_opcodes_04 {
LWS_WS_OPCODE_04__CONTINUATION = 0,
LWS_WS_OPCODE_04__CLOSE = 1,
LWS_WS_OPCODE_04__PING = 2,
LWS_WS_OPCODE_04__PONG = 3,
LWS_WS_OPCODE_04__TEXT_FRAME = 4,
LWS_WS_OPCODE_04__BINARY_FRAME = 5,
LWS_WS_OPCODE_04__RESERVED_6 = 6,
LWS_WS_OPCODE_04__RESERVED_7 = 7,
LWS_WS_OPCODE_04__RESERVED_8 = 8,
LWS_WS_OPCODE_04__RESERVED_9 = 9,
LWS_WS_OPCODE_04__RESERVED_A = 0xa,
LWS_WS_OPCODE_04__RESERVED_B = 0xb,
LWS_WS_OPCODE_04__RESERVED_C = 0xc,
LWS_WS_OPCODE_04__RESERVED_D = 0xd,
LWS_WS_OPCODE_04__RESERVED_E = 0xe,
LWS_WS_OPCODE_04__RESERVED_F = 0xf,
};
enum lws_websocket_opcodes_07 {
LWS_WS_OPCODE_07__CONTINUATION = 0,
LWS_WS_OPCODE_07__TEXT_FRAME = 1,
LWS_WS_OPCODE_07__BINARY_FRAME = 2,
LWS_WS_OPCODE_07__NOSPEC__MUX = 7,
/* control extensions 8+ */
LWS_WS_OPCODE_07__CLOSE = 8,
LWS_WS_OPCODE_07__PING = 9,
LWS_WS_OPCODE_07__PONG = 0xa,
};
enum lws_connection_states {
WSI_STATE_HTTP,
WSI_STATE_HTTP_HEADERS,
WSI_STATE_DEAD_SOCKET,
WSI_STATE_ESTABLISHED,
WSI_STATE_CLIENT_UNCONNECTED,
WSI_STATE_RETURNED_CLOSE_ALREADY,
WSI_STATE_AWAITING_CLOSE_ACK,
};
enum lws_rx_parse_state {
LWS_RXPS_NEW,
LWS_RXPS_SEEN_76_FF,
LWS_RXPS_PULLING_76_LENGTH,
LWS_RXPS_EAT_UNTIL_76_FF,
LWS_RXPS_04_MASK_NONCE_1,
LWS_RXPS_04_MASK_NONCE_2,
LWS_RXPS_04_MASK_NONCE_3,
LWS_RXPS_04_FRAME_HDR_1,
LWS_RXPS_04_FRAME_HDR_LEN,
LWS_RXPS_04_FRAME_HDR_LEN16_2,
LWS_RXPS_04_FRAME_HDR_LEN16_1,
LWS_RXPS_04_FRAME_HDR_LEN64_8,
LWS_RXPS_04_FRAME_HDR_LEN64_7,
LWS_RXPS_04_FRAME_HDR_LEN64_6,
LWS_RXPS_04_FRAME_HDR_LEN64_5,
LWS_RXPS_04_FRAME_HDR_LEN64_4,
LWS_RXPS_04_FRAME_HDR_LEN64_3,
LWS_RXPS_04_FRAME_HDR_LEN64_2,
LWS_RXPS_04_FRAME_HDR_LEN64_1,
LWS_RXPS_07_COLLECT_FRAME_KEY_1,
LWS_RXPS_07_COLLECT_FRAME_KEY_2,
LWS_RXPS_07_COLLECT_FRAME_KEY_3,
LWS_RXPS_07_COLLECT_FRAME_KEY_4,
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED
};
enum connection_mode {
LWS_CONNMODE_WS_SERVING,
LWS_CONNMODE_WS_CLIENT,
/* transient modes */
LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY,
LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE,
LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY,
LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT,
LWS_CONNMODE_WS_CLIENT_PENDING_CANDIDATE_CHILD,
/* special internal types */
LWS_CONNMODE_SERVER_LISTENER,
LWS_CONNMODE_BROADCAST_PROXY_LISTENER,
LWS_CONNMODE_BROADCAST_PROXY
};
#define LWS_FD_HASH(fd) ((fd ^ (fd >> 8) ^ (fd >> 16)) % FD_HASHTABLE_MODULUS)
struct libwebsocket_fd_hashtable {
struct libwebsocket *wsi[MAX_CLIENTS + 1];
int length;
};
struct libwebsocket_protocols;
struct libwebsocket_context {
struct libwebsocket_fd_hashtable fd_hashtable[FD_HASHTABLE_MODULUS];
struct pollfd fds[MAX_CLIENTS * FD_HASHTABLE_MODULUS + 1];
int fds_count;
int listen_port;
char http_proxy_address[256];
char canonical_hostname[1024];
unsigned int http_proxy_port;
unsigned int options;
unsigned long last_timeout_check_s;
int fd_random;
#ifdef LWS_OPENSSL_SUPPORT
int use_ssl;
SSL_CTX *ssl_ctx;
SSL_CTX *ssl_client_ctx;
#endif
struct libwebsocket_protocols *protocols;
int count_protocols;
struct libwebsocket_extension *extensions;
};
enum pending_timeout {
NO_PENDING_TIMEOUT = 0,
PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE,
PENDING_TIMEOUT_ESTABLISH_WITH_SERVER,
PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE,
PENDING_TIMEOUT_AWAITING_PING,
PENDING_TIMEOUT_CLOSE_ACK,
PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE,
};
/*
* This is totally opaque to code using the library. It's exported as a
* forward-reference pointer-only declaration; the user can use the pointer with
* other APIs to get information out of it.
*/
struct libwebsocket {
const struct libwebsocket_protocols *protocol;
struct libwebsocket_extension *
active_extensions[LWS_MAX_EXTENSIONS_ACTIVE];
void *active_extensions_user[LWS_MAX_EXTENSIONS_ACTIVE];
int count_active_extensions;
enum lws_connection_states state;
char name_buffer[LWS_MAX_HEADER_NAME_LENGTH];
int name_buffer_pos;
int current_alloc_len;
enum lws_token_indexes parser_state;
struct lws_tokens utf8_token[WSI_TOKEN_COUNT];
int ietf_spec_revision;
char rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + MAX_USER_RX_BUFFER +
LWS_SEND_BUFFER_POST_PADDING];
int rx_user_buffer_head;
enum libwebsocket_write_protocol rx_frame_type;
int protocol_index_for_broadcast_proxy;
enum pending_timeout pending_timeout;
unsigned long pending_timeout_limit;
int sock;
enum lws_rx_parse_state lws_rx_parse_state;
char extension_data_pending;
struct libwebsocket *candidate_children_list;
struct libwebsocket *extension_handles;
/* 04 protocol specific */
char key_b64[150];
unsigned char masking_key_04[20];
unsigned char frame_masking_nonce_04[4];
unsigned char frame_mask_04[20];
unsigned char frame_mask_index;
size_t rx_packet_length;
unsigned char opcode;
unsigned char final;
int pings_vs_pongs;
unsigned char (*xor_mask)(struct libwebsocket *, unsigned char);
char all_zero_nonce;
enum lws_close_status close_reason;
/* 07 specific */
char this_frame_masked;
/* client support */
char initial_handshake_hash_base64[30];
enum connection_mode mode;
char *c_path;
char *c_host;
char *c_origin;
char *c_protocol;
callback_function *c_callback;
char *c_address;
int c_port;
#ifdef LWS_OPENSSL_SUPPORT
SSL *ssl;
BIO *client_bio;
int use_ssl;
#endif
void *user_space;
};
extern int
libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c);
extern int
libwebsocket_parse(struct libwebsocket *wsi, unsigned char c);
extern int
libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi,
unsigned char *buf, size_t len);
extern int
libwebsocket_read(struct libwebsocket_context *context,
struct libwebsocket *wsi,
unsigned char *buf, size_t len);
extern int
lws_b64_selftest(void);
extern unsigned char
xor_no_mask(struct libwebsocket *wsi, unsigned char c);
extern unsigned char
xor_mask_04(struct libwebsocket *wsi, unsigned char c);
extern unsigned char
xor_mask_05(struct libwebsocket *wsi, unsigned char c);
extern struct libwebsocket *
wsi_from_fd(struct libwebsocket_context *context, int fd);
extern int
insert_wsi(struct libwebsocket_context *context, struct libwebsocket *wsi);
extern int
delete_from_fd(struct libwebsocket_context *context, int fd);
extern void
libwebsocket_set_timeout(struct libwebsocket *wsi,
enum pending_timeout reason, int secs);
extern int
lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len);
extern void
libwebsocket_service_timeout_check(struct libwebsocket_context *context,
struct libwebsocket *wsi, unsigned int sec);
extern struct libwebsocket *
__libwebsocket_client_connect_2(struct libwebsocket_context *context,
struct libwebsocket *wsi);
extern struct libwebsocket *
libwebsocket_create_new_server_wsi(struct libwebsocket_context *context);
extern char *
libwebsockets_generate_client_handshake(struct libwebsocket_context *context,
struct libwebsocket *wsi, char *pkt);
extern int
lws_handle_POLLOUT_event(struct libwebsocket_context *context,
struct libwebsocket *wsi, struct pollfd *pollfd);
extern int
lws_any_extension_handled(struct libwebsocket_context *context,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons r,
void *v, size_t len);
extern void *
lws_get_extension_user_matching_ext(struct libwebsocket *wsi,
struct libwebsocket_extension *ext);
extern int
lws_client_interpret_server_handshake(struct libwebsocket_context *context,
struct libwebsocket *wsi);
extern int
libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c);
extern int
lws_issue_raw_ext_access(struct libwebsocket *wsi,
unsigned char *buf, size_t len);
#ifndef LWS_OPENSSL_SUPPORT
unsigned char *
SHA1(const unsigned char *d, size_t n, unsigned char *md);
void
MD5(const unsigned char *input, int ilen, unsigned char *output);
#endif

View File

@@ -0,0 +1,326 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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.
*/
/*
* FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
* based on: http://csrc.nist.gov/fips/fip180-1.txt
* implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
*/
#include <sys/types.h>
#ifdef WIN32
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 4321 /* to show byte order (taken from gcc) */
#endif
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 1234
#endif
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif
typedef unsigned __int64 u_int64_t;
#undef __P
#ifndef __P
#if __STDC__
#define __P(protos) protos
#else
#define __P(protos) ()
#endif
#endif
#define bzero(b, len) (memset((b), '\0', (len)), (void) 0)
#else
#include <sys/stat.h>
#include <sys/cdefs.h>
#include <sys/time.h>
#endif
#include <string.h>
struct sha1_ctxt {
union {
unsigned char b8[20];
unsigned int b32[5];
} h;
union {
unsigned char b8[8];
u_int64_t b64[1];
} c;
union {
unsigned char b8[64];
unsigned int b32[16];
} m;
unsigned char count;
};
/* sanity check */
#if BYTE_ORDER != BIG_ENDIAN
# if BYTE_ORDER != LITTLE_ENDIAN
# define unsupported 1
# endif
#endif
#ifndef unsupported
/* constant table */
static unsigned int _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
#define K(t) _K[(t) / 20]
#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
#define F1(b, c, d) (((b) ^ (c)) ^ (d))
#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
#define F3(b, c, d) (((b) ^ (c)) ^ (d))
#define S(n, x) (((x) << (n)) | ((x) >> (32 - n)))
#define H(n) (ctxt->h.b32[(n)])
#define COUNT (ctxt->count)
#define BCOUNT (ctxt->c.b64[0] / 8)
#define W(n) (ctxt->m.b32[(n)])
#define PUTBYTE(x) { \
ctxt->m.b8[(COUNT % 64)] = (x); \
COUNT++; \
COUNT %= 64; \
ctxt->c.b64[0] += 8; \
if (COUNT % 64 == 0) \
sha1_step(ctxt); \
}
#define PUTPAD(x) { \
ctxt->m.b8[(COUNT % 64)] = (x); \
COUNT++; \
COUNT %= 64; \
if (COUNT % 64 == 0) \
sha1_step(ctxt); \
}
static void sha1_step __P((struct sha1_ctxt *));
static void
sha1_step(struct sha1_ctxt *ctxt)
{
unsigned int a, b, c, d, e, tmp;
size_t t, s;
#if BYTE_ORDER == LITTLE_ENDIAN
struct sha1_ctxt tctxt;
memcpy(&tctxt.m.b8[0], &ctxt->m.b8[0], 64);
ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2];
ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0];
ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6];
ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4];
ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10];
ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8];
ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14];
ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12];
ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18];
ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16];
ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22];
ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20];
ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26];
ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24];
ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30];
ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28];
ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34];
ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32];
ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38];
ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36];
ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42];
ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40];
ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46];
ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44];
ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50];
ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48];
ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54];
ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52];
ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58];
ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56];
ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62];
ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60];
#endif
a = H(0); b = H(1); c = H(2); d = H(3); e = H(4);
for (t = 0; t < 20; t++) {
s = t & 0x0f;
if (t >= 16)
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^
W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 20; t < 40; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^
W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 40; t < 60; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^
W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 60; t < 80; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^
W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
H(0) = H(0) + a;
H(1) = H(1) + b;
H(2) = H(2) + c;
H(3) = H(3) + d;
H(4) = H(4) + e;
bzero(&ctxt->m.b8[0], 64);
}
/*------------------------------------------------------------*/
void
sha1_init(struct sha1_ctxt *ctxt)
{
bzero(ctxt, sizeof(struct sha1_ctxt));
H(0) = 0x67452301;
H(1) = 0xefcdab89;
H(2) = 0x98badcfe;
H(3) = 0x10325476;
H(4) = 0xc3d2e1f0;
}
void
sha1_pad(struct sha1_ctxt *ctxt)
{
size_t padlen; /*pad length in bytes*/
size_t padstart;
PUTPAD(0x80);
padstart = COUNT % 64;
padlen = 64 - padstart;
if (padlen < 8) {
bzero(&ctxt->m.b8[padstart], padlen);
COUNT += padlen;
COUNT %= 64;
sha1_step(ctxt);
padstart = COUNT % 64; /* should be 0 */
padlen = 64 - padstart; /* should be 64 */
}
bzero(&ctxt->m.b8[padstart], padlen - 8);
COUNT += (padlen - 8);
COUNT %= 64;
#if BYTE_ORDER == BIG_ENDIAN
PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]);
PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]);
PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]);
PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]);
#else
PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]);
PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]);
PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]);
PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]);
#endif
}
void
sha1_loop(struct sha1_ctxt *ctxt, const unsigned char *input, size_t len)
{
size_t gaplen;
size_t gapstart;
size_t off;
size_t copysiz;
off = 0;
while (off < len) {
gapstart = COUNT % 64;
gaplen = 64 - gapstart;
copysiz = (gaplen < len - off) ? gaplen : len - off;
memcpy(&ctxt->m.b8[gapstart], &input[off], copysiz);
COUNT += copysiz;
COUNT %= 64;
ctxt->c.b64[0] += copysiz * 8;
if (COUNT % 64 == 0)
sha1_step(ctxt);
off += copysiz;
}
}
void
sha1_result(struct sha1_ctxt *ctxt, void *digest0)
{
unsigned char *digest;
digest = (unsigned char *)digest0;
sha1_pad(ctxt);
#if BYTE_ORDER == BIG_ENDIAN
memcpy(digest, &ctxt->h.b8[0], 20);
#else
digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2];
digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0];
digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6];
digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4];
digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10];
digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8];
digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14];
digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12];
digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18];
digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16];
#endif
}
/*
* This should look and work like the libcrypto implementation
*/
unsigned char *
SHA1(const unsigned char *d, size_t n, unsigned char *md)
{
struct sha1_ctxt ctx;
sha1_init(&ctx);
sha1_loop(&ctx, d, n);
sha1_result(&ctx, (void *)md);
return md;
}
#endif /*unsupported*/