代码拉取完成,页面将自动刷新
同步操作将从 WolfCS/stund 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/*
This program takes no arguments. It opens the STUN tcp port and rus a tls server
on it.
*/
#include <sys/types.h>
#include <string.h>
#include <openssl/e_os2.h>
#include <openssl/evp.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/pkcs7.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/ssl.h>
#ifdef WIN32
#include <errno.h>
#include <winsock2.h>
#include <io.h>
#endif
#ifndef WIN32
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#endif
#ifdef WIN32
# include <windows.h>
# include <winbase.h>
# include <errno.h>
# include <winsock2.h>
# include <io.h>
typedef unsigned int u_int32_t;
#endif
#include <cassert>
#include <fcntl.h>
#include <iostream>
#include <cstdlib>
#include <stdio.h>
#ifdef __MACH__
typedef int socklen_t;
#endif
#include "stun.h"
using namespace std;
#define MAX_CONNECTIONS 64
#ifdef WIN32
typedef int socklen_t;
//#define errno WSAGetLastError()
typedef SOCKET Socket;
#else
typedef int Socket;
static const Socket INVALID_SOCKET = -1;
static const int SOCKET_ERROR = -1;
#endif
// TODO - !cj! - need to deal with closing connections
void makeSocketNonBlocking(Socket fd) {
#if WIN32
unsigned long noBlock = 1;
int errNoBlock = ioctlsocket( fd, FIONBIO , &noBlock );
if ( errNoBlock != 0 )
{
assert(0);
}
#else
int flags = fcntl(fd, F_GETFL, 0);
int errNoBlock = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
if (errNoBlock != 0) // !cj! I may have messed up this line
{
assert(0);
}
#endif
}
int main() {
#ifdef WIN32
WORD wVersionRequested = MAKEWORD( 2, 2 );
WSADATA wsaData;
int err;
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
// could not find a usable WinSock DLL
//cerr << "Could not load winsock" << endl;
assert(0);// is this is failing, try a different version that 2.2, 1.0 or later will likely work
exit(1);
}
#endif
// contexts for each connection
SSL* ssl[MAX_CONNECTIONS];
// buffers for each connection
BIO* bio[MAX_CONNECTIONS];
// file descriptors for each connection
Socket fd[MAX_CONNECTIONS];
// ip address of other side of connection
int peerip[MAX_CONNECTIONS];
// root cert list
X509_STORE* certAuthorities;
// my public cert
X509* publicCert;
// my private key
EVP_PKEY* privateKey;
// SSL Context
SSL_CTX* ctx;
Socket mFd;
char* password = "password";
for (int i = 0; i < MAX_CONNECTIONS; i++) {
fd[i] = -1;
bio[i] = 0;
ssl[i] = 0;
}
// load public cert
FILE* fp = fopen("id.pem", "rb");
if (!fp) {
cerr << "Could not read public cert" << endl;
exit(1);
}
publicCert = PEM_read_X509(fp, NULL, NULL, NULL);
if (!publicCert) {
cerr << "Error reading contents of public cert" << endl;
exit(1);
}
cerr << "Loaded public cert" << endl;
// load private key
fp = fopen("id_key.pem", "rb");
if (!fp) {
cerr << "Could not read private key" << endl;
exit(1);
}
privateKey = PEM_read_PrivateKey(fp, NULL, NULL, password);
if (!privateKey) {
cerr << "Error reading contents of private key file " << endl;
exit(1);
}
cerr << "Loaded private key " << endl;
// load root certs
certAuthorities = X509_STORE_new();
assert( certAuthorities);
if (X509_STORE_load_locations(certAuthorities, "root.pem", NULL) != 1) {
cerr << "Error reading contents of root cert file " << endl;
}
cerr << "Loaded public CAs" << endl;
// set up main security context
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_ciphers();
OpenSSL_add_all_digests();
ERR_load_crypto_strings();
ctx = SSL_CTX_new(TLSv1_method());
assert( ctx);
int ok;
ok = SSL_CTX_use_certificate(ctx, publicCert);
assert( ok == 1);
ok = SSL_CTX_use_PrivateKey(ctx, privateKey);
assert( ok == 1);
assert( certAuthorities);
SSL_CTX_set_cert_store(ctx, certAuthorities);
// open a socket to listen for requests on
mFd = socket(PF_INET, SOCK_STREAM, 0);
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(STUN_PORT);
if (bind(mFd, (struct sockaddr*) &addr, sizeof(addr)) == SOCKET_ERROR) {
int err = errno;
if (err == EADDRINUSE) {
cerr << "Port already in use" << endl;
} else {
cerr << "Could not bind to port" << endl;
}
exit(0);
}
makeSocketNonBlocking(mFd);
int e = listen(mFd, 64);
if (e != 0) {
assert(0);
}
cerr << "Ready for requests" << endl;
while (true) {
// set up the read fd set for select
fd_set read;
FD_ZERO(&read);
int size = 0;
FD_SET(mFd, &read);
size = mFd + 1;
for (int i = 0; i < MAX_CONNECTIONS; i++) {
if (fd[i] > 0) {
FD_SET(fd[i], &read);
size = (int(fd[i] + 1) > size) ? int(fd[i] + 1) : size;
}
}
// do a select
unsigned long ms = 500;
struct timeval tv;
tv.tv_sec = (ms / 1000);
tv.tv_usec = (ms % 1000) * 1000;
int e = select(size, &read, NULL, NULL, &tv);
cerr << ".";
// process any new connections
if (FD_ISSET(mFd, &read)) {
cerr << "Got a new connection" << endl;
// find an unused connection
int i = 0;
for (; i < MAX_CONNECTIONS; i++) {
if (fd[i] == -1) {
break;
}
}
if (i >= MAX_CONNECTIONS) {
cerr << "Ran out of connections to use " << endl;
break;
}
struct sockaddr_in peer;
int peerLen = sizeof(peer);
fd[i] = accept(mFd, (struct sockaddr*) &peer, (socklen_t*) &peerLen);
if (fd[i] == -1) {
int err = errno;
cerr << "Error on accept: " << strerror(err) << endl;
break;
}
int* ptr = (int*) (&peer.sin_addr);
peerip[i] = *ptr;
ssl[i] = NULL;
ssl[i] = SSL_new(ctx);
assert(ssl[i]);
bio[i] = BIO_new_socket(fd[i], 0/*close flag*/);
assert( bio[i]);
SSL_set_bio(ssl[i], bio[i], bio[i]);
int ok = 0;
ok = SSL_accept(ssl[i]);
if (ok != 1) {
int err = SSL_get_error(ssl[i], ok);
char buf[256];
ERR_error_string_n(err, buf, sizeof(buf));
cerr << "ssl connection failed " << endl;
bio[i] = NULL;
}
makeSocketNonBlocking(fd[i]);
}
// process reads and writes
for (int i = 0; i < MAX_CONNECTIONS; i++) {
if (ssl[i])
if (FD_ISSET( fd[i], &read) || SSL_pending(ssl[i])) {
cerr << "got a message on connection " << i << endl;
char buf[STUN_MAX_MESSAGE_SIZE];
int ret = SSL_read(ssl[i], buf, sizeof(buf));
if (ret < 0) {
int err = SSL_get_error(ssl[i], ret);
switch (err) {
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_NONE: {
cerr << "Got TLS read got condition of " << err << endl;
}
break;
default: {
char buf[256];
ERR_error_string_n(err, buf, sizeof(buf));
cerr << "Got TLS read error " << err << " " << buf << endl;
}
break;
}
// !cj! - big mem leak here - need to close and cleanup
closesocket(fd[i]);
fd[i] = -1;
ssl[i] = 0;
}
cerr << "Received message with " << ret << " bytes" << endl;
StunAddress4 from;
StunAddress4 myAddr;
StunAddress4 altAddr;
StunMessage resp;
StunAddress4 destination;
StunAtrString hmacPassword;
bool changePort;
bool changeIp;
from.addr = peerip[i];
bool ok = stunServerProcessMsg(buf, ret, from, myAddr, altAddr, &resp, &destination, &hmacPassword,
&changePort, &changeIp, true /*verbose*/);
if (!ok) {
cerr << "Message did not parse - closeing conneciton " << i << endl;
closesocket(fd[i]);
fd[i] = -1;
ssl[i] = 0;
}
if (ok) {
int len = stunEncodeMessage(resp, buf, sizeof(buf), hmacPassword);
ret = SSL_write(ssl[i], (const char*) buf, len);
if (ret < 0) {
int err = SSL_get_error(ssl[i], ret);
switch (err) {
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_NONE: {
cerr << "Got TLS write got codition of " << err << endl;
}
break;
default: {
cerr << "Got TLS write error " << err << endl;
}
break;
}
// !cj! big mem leak - need to cleanup
closesocket(fd[i]);
fd[i] = -1;
ssl[i] = 0;
}
}
}
}
}
return 0;
}
/* ====================================================================
* The Vovida Software License, Version 1.0
*
* Copyright (c) 2000 Vovida Networks, Inc. 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. The names "VOCAL", "Vovida Open Communication Application Library",
* and "Vovida Open Communication Application Library (VOCAL)" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact vocal@vovida.org.
*
* 4. Products derived from this software may not be called "VOCAL", nor
* may "VOCAL" appear in their name, without prior written
* permission of Vovida Networks, Inc.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
* IN EXCESS OF $1,000, NOR FOR ANY 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.
*
* ====================================================================
*
* This software consists of voluntary contributions made by Vovida
* Networks, Inc. and many individuals on behalf of Vovida Networks,
* Inc. For more information on Vovida Networks, Inc., please see
* <http://www.vovida.org/>.
*
*/
// Local Variables:
// mode:c++
// c-file-style:"ellemtel"
// c-file-offsets:((case-label . +))
// indent-tabs-mode:nil
// End:
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。