Ejemplo n.º 1
0
int ws_handshake(wsh_t *wsh)
{
	char key[256] = "";
	char version[5] = "";
	char proto[256] = "";
	char proto_buf[384] = "";
	char input[256] = "";
	unsigned char output[SHA1_HASH_SIZE] = "";
	char b64[256] = "";
	char respond[512] = "";
	ssize_t bytes;
	char *p, *e = 0;

	if (wsh->sock == ws_sock_invalid) {
		return -3;
	}

	while((bytes = ws_raw_read(wsh, wsh->buffer + wsh->datalen, wsh->buflen - wsh->datalen, WS_BLOCK)) > 0) {
		wsh->datalen += bytes;
		if (strstr(wsh->buffer, "\r\n\r\n") || strstr(wsh->buffer, "\n\n")) {
			break;
		}
	}

	if (bytes > sizeof(wsh->buffer) -1) {
		goto err;
	}

	*(wsh->buffer + wsh->datalen) = '\0';
	
	if (strncasecmp(wsh->buffer, "GET ", 4)) {
		goto err;
	}
	
	p = wsh->buffer + 4;
	
	e = strchr(p, ' ');
	if (!e) {
		goto err;
	}

	wsh->uri = malloc((e-p) + 1);
	strncpy(wsh->uri, p, e-p);
	*(wsh->uri + (e-p)) = '\0';

	cheezy_get_var(wsh->buffer, "Sec-WebSocket-Key", key, sizeof(key));
	cheezy_get_var(wsh->buffer, "Sec-WebSocket-Version", version, sizeof(version));
	cheezy_get_var(wsh->buffer, "Sec-WebSocket-Protocol", proto, sizeof(proto));
	
	if (!*key) {
		goto err;
	}
		
	snprintf(input, sizeof(input), "%s%s", key, WEBSOCKET_GUID);
	sha1_digest(output, input);
	b64encode((unsigned char *)output, SHA1_HASH_SIZE, (unsigned char *)b64, sizeof(b64));

	if (*proto) {
		snprintf(proto_buf, sizeof(proto_buf), "Sec-WebSocket-Protocol: %s\r\n", proto);
	}

	snprintf(respond, sizeof(respond), 
			 "HTTP/1.1 101 Switching Protocols\r\n"
			 "Upgrade: websocket\r\n"
			 "Connection: Upgrade\r\n"
			 "Sec-WebSocket-Accept: %s\r\n"
			 "%s\r\n",
			 b64,
			 proto_buf);
	respond[511] = 0;

	if (ws_raw_write(wsh, respond, strlen(respond)) != (ssize_t)strlen(respond)) {
		goto err;
	}

	wsh->handshake = 1;

	return 0;

 err:

	if (!wsh->stay_open) {

		snprintf(respond, sizeof(respond), "HTTP/1.1 400 Bad Request\r\n"
				 "Sec-WebSocket-Version: 13\r\n\r\n");
		respond[511] = 0;

		ws_raw_write(wsh, respond, strlen(respond));

		ws_close(wsh, WS_NONE);
	}

	return -1;

}
Ejemplo n.º 2
0
void client_run(int client_socket, char *local_ip, int local_port, char *remote_ip, int remote_port)
{
    char sendbuf[RCVBUFSIZE], recvbuf[RCVBUFSIZE], infobuf[RCVBUFSIZE];
	struct sockaddr_in addr = {0}, sendaddr = {0};
    int read_bytes;
	int usock;
	int reuse_addr = 1;
    fax_state_t fax;
	char tmp[512], fn[512], *file_name = "/tmp/test.tiff";
	int send_fax = FALSE;
	int g711 = 0;
	int pcmu = 0;

	snprintf(sendbuf, sizeof(sendbuf), "connect\n\n");
	send(client_socket, sendbuf, strlen(sendbuf), 0);

    if ((read_bytes = recv(client_socket, infobuf, sizeof(infobuf), 0)) < 0) {
        die("recv() failed");
	}

#if SOCKET2ME_DEBUG
	printf("READ [%s]\n", infobuf);
#endif

	if (cheezy_get_var(infobuf, "Channel-Read-Codec-Name", tmp, sizeof(tmp))) {
		if (!strcasecmp(tmp, "pcmu")) {
			g711 = 1;
			pcmu = 1;
		} else if (!strcasecmp(tmp, "pcma")) {
			g711 = 1;
		}
	}


	snprintf(sendbuf, sizeof(sendbuf), "sendmsg\n"
			 "call-command: unicast\n"
			 "local-ip: %s\n"
			 "local-port: %d\n"
			 "remote-ip: %s\n"
			 "remote-port: %d\n"
			 "transport: udp\n"
			 "%s"
			 "\n",
			 local_ip, local_port,
			 remote_ip, remote_port,
			 g711 ? "flags: native\n" : ""
			 );

	
	if (cheezy_get_var(infobuf, "variable_fax_file_name", fn, sizeof(fn))) {
		file_name = fn;
	}

	if (cheezy_get_var(infobuf, "variable_fax_mode", tmp, sizeof(tmp))) {
		if (!strcasecmp(tmp, "send")) {
			send_fax = TRUE;
		}
	}

	if (cheezy_get_var(infobuf, "variable_fax_preexec", tmp, sizeof(tmp))) {
	  set_vars(infobuf);
	  system(tmp);
	}

#if SOCKET2ME_DEBUG
	printf("SEND: [%s]\n", sendbuf);
#endif
	send(client_socket, sendbuf, strlen(sendbuf), 0);

	memset(recvbuf, 0, sizeof(recvbuf));
    if ((read_bytes = recv(client_socket, recvbuf, sizeof(recvbuf), 0)) < 0) {
        die("recv() failed");
	}
#if SOCKET2ME_DEBUG
	printf("READ [%s]\n", recvbuf);
#endif
	
	if ((usock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
        die("socket() failed");
	}

	setsockopt(usock, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));

    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    /*addr.sin_addr.s_addr = inet_addr(remote_ip);*/
    addr.sin_port = htons(remote_port);

    sendaddr.sin_family = AF_INET;
    sendaddr.sin_addr.s_addr = inet_addr(local_ip);
    sendaddr.sin_port = htons(local_port);
	
    if (bind(usock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        die("bind() failed");
	}

	printf("%s Fax filename: [%s] from %s:%d -> %s:%d\n", send_fax ? "Sending" : "Receiving", file_name, local_ip, local_port, remote_ip, remote_port);
	
    fax_init(&fax, send_fax);
    t30_set_local_ident(&fax.t30_state, "Socket 2 ME");
    t30_set_header_info(&fax.t30_state, "Socket 2 ME");
	if (send_fax) {
		t30_set_tx_file(&fax.t30_state, file_name, -1, -1);
	} else {
		t30_set_rx_file(&fax.t30_state, file_name, -1);
	}
    t30_set_phase_b_handler(&fax.t30_state, phase_b_handler, NULL);
    t30_set_phase_d_handler(&fax.t30_state, phase_d_handler, NULL);
    t30_set_phase_e_handler(&fax.t30_state, phase_e_handler, NULL);
    t30_set_document_handler(&fax.t30_state, document_handler, NULL);

    t30_set_ecm_capability(&fax.t30_state, TRUE);
    t30_set_supported_compressions(&fax.t30_state, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);

    t30_set_supported_image_sizes(&fax.t30_state, T30_SUPPORT_US_LETTER_LENGTH | T30_SUPPORT_US_LEGAL_LENGTH | T30_SUPPORT_UNLIMITED_LENGTH
                                  | T30_SUPPORT_215MM_WIDTH | T30_SUPPORT_255MM_WIDTH | T30_SUPPORT_303MM_WIDTH);
    t30_set_supported_resolutions(&fax.t30_state, T30_SUPPORT_STANDARD_RESOLUTION | T30_SUPPORT_FINE_RESOLUTION | T30_SUPPORT_SUPERFINE_RESOLUTION
                                  | T30_SUPPORT_R8_RESOLUTION | T30_SUPPORT_R16_RESOLUTION);

	for (;;) {
		struct sockaddr_in local_addr = {0};
        size_t cliAddrLen = sizeof(local_addr);
		unsigned char audiobuf[1024], rawbuf[1024], outbuf[1024];
		short *usebuf = NULL;
		int tx, tx_bytes, bigger, sample_count;
		fd_set ready;

		FD_ZERO(&ready);

		FD_SET(usock, &ready);
		FD_SET(client_socket, &ready);
		
		bigger = usock > client_socket ? usock : client_socket;
		select(++bigger, &ready, NULL, NULL, NULL);
		
		if (FD_ISSET(client_socket, &ready)) {
			memset(recvbuf, 0, sizeof(recvbuf));
			if ((read_bytes = recv(client_socket, recvbuf, sizeof(recvbuf), 0)) < 0) {
				die("recv() failed");
			}

			if (read_bytes == 0) {
				break;
			}
#if SOCKET2ME_DEBUG
			printf("READ [%s]\n", recvbuf);
#endif
		}

		if (!FD_ISSET(usock, &ready)) {
			continue;
		}

        if ((read_bytes = recvfrom(usock, audiobuf, sizeof(audiobuf), 0, (struct sockaddr *) &local_addr, &cliAddrLen)) < 0) {
			die("recvfrom() failed");
		}

		if (g711) {
			int i;
			short *rp = (short *) rawbuf;
			
			for (i = 0; i < read_bytes; i++) {
				if (pcmu) {
					rp[i] = ulaw_to_linear(audiobuf[i]);
				} else {
					rp[i] = alaw_to_linear(audiobuf[i]);
				}
			}
			usebuf = rp;
			sample_count = read_bytes;
		} else {
			usebuf = (short *) audiobuf;
			sample_count = read_bytes / 2;
		}
		
		fax_rx(&fax, usebuf, sample_count);
#if SOCKET2ME_DEBUG
		printf("Handling client %s:%d %d bytes\n", inet_ntoa(local_addr.sin_addr), ntohs(local_addr.sin_port), read_bytes);
#endif

		
		if ((tx = fax_tx(&fax, (short *)outbuf, sample_count)) < 0) {
            printf("Fax Error\n");
			break;
        } else if (!tx) {
			continue;
		}
		

		if (g711) {
			int i;
			short *bp = (short *) outbuf;
			for (i = 0; i < tx; i++) {
				if (pcmu) {
					rawbuf[i] = linear_to_ulaw(bp[i]);
				} else {
					rawbuf[i] = linear_to_alaw(bp[i]);
				}
			}
			usebuf = (short *) rawbuf;
			tx_bytes = tx;
		} else {
			usebuf = (short *)outbuf;
			tx_bytes = tx * 2;
		}	
		

		cliAddrLen = sizeof(sendaddr);
        if (sendto(usock, usebuf, tx_bytes, 0, (struct sockaddr *) &sendaddr, sizeof(sendaddr)) != tx_bytes) {
			die("sendto() sent a different number of bytes than expected");
		}
	}

	close(client_socket);
	close(usock);
		
    t30_terminate(&fax.t30_state);
    fax_release(&fax);

    if (cheezy_get_var(infobuf, "variable_fax_postexec", tmp, sizeof(tmp))) {
      set_vars(infobuf);
      system(tmp);
    }
	printf("Done\n");
	snprintf(sendbuf, sizeof(sendbuf), "hangup\n\n");
	send(client_socket, sendbuf, strlen(sendbuf), 0);
	
}