⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mserver.mx

📁 一个内存数据库的源代码这是服务器端还有客户端
💻 MX
📖 第 1 页 / 共 4 页
字号:
		if (sock >= 0)			FD_SET(sock, &fds);#ifdef HAVE_SYS_UN_H		if (usock >= 0)			FD_SET(usock, &fds);#endif		/* Wait up to 0.5 seconds. */		tv.tv_sec = 0;		tv.tv_usec = 500;		/* temporarily use msgsock to record the larger of sock and usock */		msgsock = sock;#ifdef HAVE_SYS_UN_H		if (usock > sock)			msgsock = usock;#endif		retval = select(msgsock + 1, &fds, NULL, NULL, &tv);		if (retval == 0) {			/* nothing interesting has happened */			continue;		}		if (retval < 0) {			if (MT_geterrno() != EINTR) {				msg = "select failed";				goto error;			}			continue;		}		if (sock >= 0 && FD_ISSET(sock, &fds)) {			if ((msgsock = accept(sock, (SOCKPTR) 0, (SOCKLEN *) 0)) < 0) {				if (MT_geterrno() != EINTR || serveractive==FALSE) {					msg = "accept failed\n";					goto error;				}				continue;			}#ifdef HAVE_SYS_UN_H		} else if (usock >= 0 && FD_ISSET(usock, &fds)) {			if ((msgsock = accept(usock, (SOCKPTR) 0, (SOCKLEN *) 0)) < 0) {				if (MT_geterrno() != EINTR) {					msg = "accept failed\n";					goto error;				}				continue;			}#endif		} else			continue;#ifdef DEBUG_SERVER		printf("server:accepted\n");		fflush(stdout);#endif		doChallenge(cmd, msgsock);	} while (1);error:	throw(IO, "mserver.listen", msg);}/** * Small utility function to call the sabaoth marchConnection function * with the right arguments.  If the socket is bound to 0.0.0.0 the * hostname address is used, to make the info usable for servers outside * localhost. */void SERVERannounce(struct in_addr addr, int port, int ssl) {	str buf = alloca(sizeof(char) * 1024);	str host = NULL;	bit bssl = ssl != 0 ? 1 : 0;	if (addr.s_addr == INADDR_ANY) {		host = alloca(sizeof(char) * (90 + 1));		gethostname(host, 90);		host[90] = '\0';	} else {		/* avoid doing this, it requires some includes that probably		 * give trouble on windowz		host = inet_ntoa(addr);		 */		host = alloca(sizeof(char) * ((3 + 1 + 3 + 1 + 3 + 1 + 3) + 1));		sprintf(host, "%u.%u.%u.%u",				(unsigned) ((ntohl(addr.s_addr) >> 24) & 0xff),				(unsigned) ((ntohl(addr.s_addr) >> 16) & 0xff),				(unsigned) ((ntohl(addr.s_addr) >> 8) & 0xff),				(unsigned) (ntohl(addr.s_addr) & 0xff));	}	if ((buf = SABAOTHmarchConnection(&ssl, &host, &port, &bssl)) != MAL_SUCCEED)		GDKfree(buf);}strSERVERlisten(int *Port, str *Usockfile, int *Maxusers, str *Cmd){	struct sockaddr_in server;	int sock = -1;	int *Sock = GDKmalloc(sizeof(int));#ifdef HAVE_SYS_UN_H	struct sockaddr_un userver;#endif	SOCKLEN length = 0;	int on = 1;	int i = 0;	MT_Id pid, *pidp = &pid;	int port;	int maxusers;	char msg[512], *cmd, *usockfile, host[512];	port = *Port;	if (Usockfile == NULL || *Usockfile == 0 || strcmp(*Usockfile, str_nil) == 0)		usockfile = NULL;	else {#ifdef HAVE_SYS_UN_H		usockfile = GDKstrdup(*Usockfile);#else		usockfile = NULL;		throw(IO, "mserver.listen", "Unix domain sockets are not supported");#endif	}	maxusers = *Maxusers;	cmd = Cmd ? GDKstrdup(*Cmd) : NULL;	maxusers = (maxusers ? maxusers : SERVERMAXUSERS);	if (port < 0 && usockfile == NULL)		throw(IO, "mserver.listen", "No port or socket file specified");	if (port >= 0) {		sock = socket(AF_INET, SOCK_STREAM, 0);		if (sock < 0)			throw(IO, "mserver.listen",					"Creation of stream socket failedi: %s",					strerror(errno));		/* In auto-sensing mode, start at the default */		/* FIXME: should be configurable via the config file */		if (*Port == 0)			port = SERVERPORT;		setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof on);		server.sin_family = AF_INET;		/* FIXME: this should be configurable via the config file */		server.sin_addr.s_addr = INADDR_ANY;		for (i = 0; i < 8; i++)			server.sin_zero[i] = 0;		length = (SOCKLEN) sizeof(server);		do {			server.sin_port = htons((unsigned short) ((port) & 0xFFFF));			if (bind(sock, (SOCKPTR) &server, length) < 0) {				/* FIXME: this should come from the config file */				if (#ifdef EADDRINUSEerrno == EADDRINUSE &&#else #ifdef WSAEADDRINUSE errno == WSAEADDRINUSE &&#endif#endif 					*Port == 0 && port < 60000) {					port++;					continue;				}				throw(IO, "mserver.listen",						"Binding to stream socket port %d failed: %s",						port, strerror(errno));			} else {				break;			}		} while (1);		if (getsockname(sock, (SOCKPTR) &server, &length) < 0)			throw(IO, "mserver.listen",					"Failed getting socket name: %s",					strerror(errno));		listen(sock, maxusers);	}#ifdef HAVE_SYS_UN_H	if (usockfile) {		usock = socket(AF_UNIX, SOCK_STREAM, 0);		if (usock < 0) {			unlink(usockfile);			throw(IO, "mserver.listen",					"Creation of Unix socket failed: %s",					strerror(errno));		}		userver.sun_family = AF_UNIX;		strncpy(userver.sun_path, usockfile, sizeof(userver.sun_path));		length = (SOCKLEN) sizeof(userver);		if (bind(usock, (SOCKPTR) & userver, length) < 0) {			unlink(usockfile);			throw(IO, "mserver.listen",					"Binding to Unix socket file %s failed: %s",					usockfile, strerror(errno));		}		listen(usock, maxusers);	}#endif#ifdef DEBUG_SERVER	THRprintf(GDKout, "#SERVERlisten:Network started at %d\n", port);#endif	threadcommand = cmd;	*Sock = sock;	if (MT_create_thread(pidp, (void (*)(void *)) SERVERlistenThread, Sock) < 0) {		throw(MAL, "mserver.listen", "Starting thread failed");	}#ifdef HAVE_SYS_UN_H	if (usockfile)		unlink(usockfile);#endif	gethostname(host, (int) 512);	(void) msg;#ifdef DEBUG_SERVER	snprintf(msg, (int) 512, "#Ready to accept connections on %s:%d\n", host, port);	stream_printf(GDKout, "%s", msg);#endif	SERVERannounce(server.sin_addr, port, 0);	return MAL_SUCCEED;}#ifdef HAVE_OPENSSLstatic char *ssl_error(const char *name, int err, int ret){	char *errstr, *s;	char buf[120];	unsigned long e;	switch (err) {	case SSL_ERROR_ZERO_RETURN:		errstr = "TLS/SSL connection has been closed";		break;	case SSL_ERROR_WANT_READ:		errstr = "The operation did not complete (read)";		break;	case SSL_ERROR_WANT_WRITE:		errstr = "The operation did not complete (write)";		break;	case SSL_ERROR_WANT_X509_LOOKUP:		errstr = "The operation did not complete (X509 lookup)";		break;	case SSL_ERROR_WANT_CONNECT:		errstr = "The operation did not complete (connect)";		break;	case SSL_ERROR_SYSCALL:		e = ERR_get_error();		if (e == 0) {			if (ret == 0) {				errstr = "EOF occurred in violation of protocol";			} else if (ret == -1) {				/* the underlying BIO reported an I/O error */				errstr = "I/O error";			} else {	/* possible? */				errstr = "Some I/O error occurred";			}		} else {			errstr = ERR_error_string(e, buf);		}		break;	case SSL_ERROR_SSL:		e = ERR_get_error();		if (e != 0)			errstr = ERR_error_string(e, buf);		else {		/* possible? */			errstr = "A failure in the SSL library occurred";		}		break;	default:		errstr = "Invalid error code";	}	s = (char*) GDKmalloc(strlen(errstr) + strlen(name) + 4);	sprintf(s, "%s: %s\n", name, errstr);	/* we allocated enough, so it fits */	return s;}static MT_Lock *mutex_buf;static voidlocking_function(int mode, int n, const char *file, int line){	(void) file;	(void) line;	if (mode & CRYPTO_LOCK){		MT_set_lock(mutex_buf[n], "locking_function");	} else {		MT_unset_lock(mutex_buf[n], "locking_function");	}}static unsigned longid_function(void){	return (unsigned long) MT_getpid();}#endif /* HAVE_OPENSSL */bat *SERVERprelude(void){#ifdef HAVE_OPENSSL	int i, nlocks;	nlocks = CRYPTO_num_locks();	mutex_buf = GDKmalloc(nlocks * sizeof(*mutex_buf));	if (mutex_buf == NULL) {		GDKsyserror("SERVERprelude: failed to allocate %d mutexes\n", nlocks);		return NULL;	}	for (i = 0; i < nlocks; i++)		MT_lock_init(&mutex_buf[i]);	CRYPTO_set_locking_callback(locking_function);	CRYPTO_set_id_callback(id_function);#endif	return NULL;}voidSERVERepilogue(void){#ifdef HAVE_OPENSSL	if (mutex_buf) {		int i, nlocks;		nlocks = CRYPTO_num_locks();		CRYPTO_set_id_callback(NULL);		CRYPTO_set_locking_callback(NULL);		for (i = 0; i < nlocks; i++)			MT_destroy_lock(mutex_buf[i]);		GDKfree(mutex_buf);		mutex_buf = NULL;	}	/* callString(mal_clients, "sabaoth.retreatConnection(...);", 0); */#endif /* HAVE_OPENSSL */	/* callString(mal_clients, "sabaoth.retreatConnection(...);", 0); */}strSERVERlistenSSL(int *Port, int *Maxusers, str keyfile, str certfile, str cmd){#ifdef HAVE_OPENSSL	struct sockaddr_in server;	int sock = -1;	SOCKLEN length = 0;	int on = 1;	int msgsock;	int i = 0;	int port = *Port;	int maxusers = *Maxusers;	SSL_CTX *ctx = NULL;	SSL *ssl = NULL;	char *msg = NULL;	if (!port)		port = SERVERSSLPORT;	if (!maxusers)		maxusers = SERVERMAXUSERS;	ctx = SSL_CTX_new(SSLv23_method());	if (ctx == NULL) {		msg = "creation of SSL context failed\n";		goto fail;	}	if (SSL_CTX_set_cipher_list(ctx, "ALL:!LOW") == 0) {		msg = "SSL_CTX_set_cipher_list failed\n";		goto fail;	}	if (keyfile && *keyfile && certfile && *certfile) {		if (SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM) < 1) {			msg = "SSL_CTX_use_PrivateKey_file failed\n";			goto fail;		}		if (SSL_CTX_use_certificate_chain_file(ctx, certfile) < 1) {			msg = "SSL_CTX_use_certificate_chain_file failed\n";			goto fail;		}	}	if (keyfile)		GDKfree(keyfile);	if (certfile)		GDKfree(certfile);	SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);	sock = socket(AF_INET, SOCK_STREAM, 0);	if (sock < 0) {		GDKsyserror("SERVERlistenSSL:creation of stream socket failed\n");		goto fail;	}@-Set server port and allow network connections from any workstation.Bind the socket to the server port.The port id should be obtained from the Homes file.@c	server.sin_family = AF_INET;	server.sin_addr.s_addr = INADDR_ANY;	server.sin_port = htons((unsigned short) ((port) & 0xFFFF));	for (i = 0; i < 8; i++)		server.sin_zero[i] = 0;	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof on);	length = (SOCKLEN) sizeof(server);	if (bind(sock, (SOCKPTR) & server, length) < 0) {		GDKsyserror("SERVERlistenSSL:binding to stream socket (%d) failed\n", port);		goto fail;	}@-Get the new information for the server socket and start listening.@c	if (getsockname(sock, (SOCKPTR) & server, &length) < 0) {		msg = "getting socket name\n";		goto fail;	}	listen(sock, maxusers);#ifdef DEBUG_SERVER	THRprintf(GDKout, "#SERVERlistenSSL:Network started at %d\n", port);#endif	do {		int retval;		struct timeval tv;		fd_set fds;		FD_ZERO(&fds);		FD_SET(sock, &fds);		/* Wait up to 0.5 seconds. */		tv.tv_sec = 0;		tv.tv_usec = 500;		retval = select(sock + 1, &fds, &fds, &fds, &tv);		if (retval == 0) {			/* nothing interesting has happened */			continue;		}		if (retval < 0) {			GDKsyserror("SERVERlistenSSL:select failed\n");			goto fail;		}		if ((msgsock = accept(sock, (SOCKPTR) 0, (SOCKLEN *) 0)) < 0) {			if (MT_geterrno() != EINTR) {				msg = "Accept failed";				goto fail;			}			continue;		}		if ((ssl = SSL_new(ctx)) == 0) {			msg = "SSL_new failed";			goto fail;		}		if (!SSL_set_fd(ssl, msgsock)) {			msg = "SSL_set_fd failed";			goto fail;		}		for (;;) {			int ret, err;			char *errstr;			ret = SSL_accept(ssl);			err = SSL_get_error(ssl, ret);			switch (err) {			case SSL_ERROR_WANT_READ:			case SSL_ERROR_WANT_WRITE:				/* try again */				continue;			case SSL_ERROR_NONE:				/* successful connect */				break;			case SSL_ERROR_WANT_CONNECT:			case SSL_ERROR_WANT_ACCEPT:			case SSL_ERROR_WANT_X509_LOOKUP:			default:				/* some error occurred */				errstr = ssl_error("SERVERlistenSSL", err, ret);				GDKsyserror(errstr);				GDKfree(errstr);				SSL_free(ssl);				close(msgsock);				goto end_loop;			}			break;		}		doChallenge(cmd, msgsock);end_loop:;	} while (1);	SSL_CTX_free(ctx);	close(sock);	if (cmd)		GDKfree(cmd);	SERVERannounce(server.sin_addr, port, 1);	return MAL_SUCCEED;fail:;	if (sock >= 0)		close(sock);	if (ctx)		SSL_CTX_free(ctx);	if (cmd)		GDKfree(cmd);	throw(IO, "mserver.listenSSL", msg);#else	(void) Port;	(void) Maxusers;	(void) keyfile;	(void) certfile;	(void) cmd;	throw(MAL, "mserver.listenSSL", "No SSL support");#endif /* HAVE_OPENSSL */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -