static void ftp_pass_info(struct connection *c, struct read_buffer *rb) { int g = get_ftp_response(c, rb, 0); if (g == -1) { setcstate(c, S_FTP_ERROR); abort_connection(c); return; } if (!g) { read_from_socket(c, c->sock1, rb, ftp_pass_info); setcstate(c, S_LOGIN); return; } if (g >= 530 && g < 540) { setcstate(c, S_FTP_LOGIN); abort_connection(c); return; } if (g >= 400) { setcstate(c, S_FTP_UNAVAIL); abort_connection(c); return; } if (ftp_options.fast_ftp) ftp_retr_file(c, rb); else ftp_send_retr_req(c, S_GETH); }
void ftp_got_user_info(struct connection *c, struct read_buffer *rb) { int g = get_ftp_response(c, rb, 0); if (g == -1) { setcstate(c, S_FTP_ERROR); abort_connection(c); return; } if (!g) { read_from_socket(c, c->sock1, rb, ftp_got_user_info); return; } if (g >= 530 && g < 540) { setcstate(c, S_FTP_LOGIN); retry_connection(c); return; } if (g >= 400) { setcstate(c, S_FTP_UNAVAIL); retry_connection(c); return; } if (g >= 200 && g < 300) { if (ftp_options.fast_ftp) ftp_dummy_info(c, rb); else ftp_send_retr_req(c, S_GETH); } else { if (ftp_options.fast_ftp) ftp_pass_info(c, rb); else { unsigned char *login; unsigned char *u; int logl = 0; login = init_str(); add_to_str(&login, &logl, "PASS "); if ((u = get_pass(c->url)) && *u) add_to_str(&login, &logl, u); else add_to_str(&login, &logl, ftp_options.anon_pass); if (u) mem_free(u); add_to_str(&login, &logl, "\r\n"); write_to_socket(c, c->sock1, login, strlen(login), ftp_sent_passwd); mem_free(login); setcstate(c, S_LOGIN); } } }
//gcc router.c -o router graph.c socket_open_read_write.c -w message_encode_decode.c -w //./router port_number int main(int argc, char *argv[]){ /*Initializing globals*/ memset(message_history_table,0,TABLE_SIZE); ROUTER_ID=atoi(argv[1]); message_count=0; //Setting up socket int port_number=ROUTER_BASE_PORT+ROUTER_ID; int my_socket=set_up_socket(port_number); char *msg_string; char c; msg *received_message; //listening now listen_again: initialize_graph(); msg_string=read_from_socket(my_socket); received_message=decode_message(msg_string); // free(msg_string); do_stuff(received_message); // printf("Press y to continue listening(you may have to press twice for assurance).n to kill the socket and exit.\n"); // c=getchar(); // c=getchar(); //if(c=='y') goto listen_again; close(my_socket); return 0; }
int main(int argc, char *argv[]) { if (argc > 1) // devo fare il dump in un file anziché a schermo dumpFile = argv[1]; // Maschera i segnali int retval; sigset_t set; sigemptyset(&set); sigaddset(&set, SIGINT); sigaddset(&set, SIGTERM); SC_OR_FAIL(pthread_sigmask(SIG_SETMASK, &set, NULL), retval, "Impossibile gestire i segnali in visualizer"); // Installa un handler per il segnale di terminazione struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = terminate; SC_OR_FAIL(sigaction(SIGUSR2, &sa, NULL), retval, "Impossibile gestire i segnali in visualizer"); unsigned int nrow = UINT_MAX; // Numero di colonne della matrice unsigned int ncol = UINT_MAX; // Numero di righe della matrice while (!mustTerminate) { if (connect_to_socket(&nrow, &ncol) && new_planet_matrix(nrow, ncol) && read_from_socket(nrow, ncol)) print_or_dump_planet_matrix(nrow, ncol); close(visualizerSocket); } DEBUG_PRINT("Visualizer sta per terminare...\n"); return EXIT_SUCCESS; }
static void smb_got_data(struct socket *socket, struct read_buffer *rb) { int len = rb->length; struct connection *conn = socket->conn; if (len < 0) { abort_connection(conn, connection_state_for_errno(errno)); return; } if (!len) { abort_connection(conn, connection_state(S_OK)); return; } socket->state = SOCKET_END_ONCLOSE; conn->received += len; if (add_fragment(conn->cached, conn->from, rb->data, len) == 1) conn->tries = 0; conn->from += len; kill_buffer_data(rb, len); read_from_socket(socket, rb, connection_state(S_TRANS), smb_got_data); }
void ftp_dummy_info(struct connection *c, struct read_buffer *rb) { int g = get_ftp_response(c, rb, 0); if (g == -1) { setcstate(c, S_FTP_ERROR); abort_connection(c); return; } if (!g) { read_from_socket(c, c->sock1, rb, ftp_dummy_info); return; } ftp_retr_file(c, rb); }
/* Called when we receive a connection on the listening socket. */ static void accept_bittorrent_peer_connection(void *____) { struct sockaddr_in addr; int peer_sock; int addrlen = sizeof(addr); struct bittorrent_peer_connection *peer; struct read_buffer *buffer; peer_sock = accept(bittorrent_socket, (struct sockaddr *) &addr, &addrlen); if (peer_sock < 0) return; if (set_nonblocking_fd(peer_sock) < 0) { close(peer_sock); return; } peer = init_bittorrent_peer_connection(peer_sock); if (!peer) { close(peer_sock); return; } peer->remote.initiater = 1; /* Just return. Failure is handled by alloc_read_buffer(). */ buffer = alloc_read_buffer(peer->socket); if (!buffer) return; read_from_socket(peer->socket, buffer, connection_state(S_TRANS), read_bittorrent_peer_handshake); add_to_list(bittorrent_peer_connections, peer); }
void finger_get_response(struct connection *c, struct read_buffer *rb) { struct cache_entry *e; int l; set_timeout(c); if (get_cache_entry(c->url, &e)) { setcstate(c, S_OUT_OF_MEM); abort_connection(c); return; } c->cache = e; if (rb->close == 2) { setcstate(c, S_OK); finger_end_request(c); return; } l = rb->len; if (c->from + l < 0) { setcstate(c, S_LARGE_FILE); abort_connection(c); return; } c->received += l; if (add_fragment(c->cache, c->from, rb->data, l) == 1) c->tries = 0; c->from += l; kill_buffer_data(rb, l); read_from_socket(c, c->sock1, rb, finger_get_response); setcstate(c, S_TRANS); }
void ftp_got_info(struct connection *c, struct read_buffer *rb) { int g = get_ftp_response(c, rb, 0); if (g == -1) { setcstate(c, S_FTP_ERROR); abort_connection(c); return; } if (!g) { read_from_socket(c, c->sock1, rb, ftp_got_info); return; } if (g >= 400) { setcstate(c, S_FTP_UNAVAIL); retry_connection(c); return; } ftp_got_user_info(c, rb); }
void finger_sent_request(struct connection *c) { struct read_buffer *rb; set_timeout(c); if (!(rb = alloc_read_buffer(c))) return; rb->close = 1; read_from_socket(c, c->sock1, rb, finger_get_response); }
void http_get_header(struct connection *c) { struct read_buffer *rb; set_timeout(c); if (!(rb = alloc_read_buffer(c))) return; rb->close = 1; read_from_socket(c, c->sock1, rb, http_got_header); }
static void read_response_from_socket(struct socket *socket) { struct read_buffer *rb = alloc_read_buffer(socket); if (rb) read_from_socket(socket, rb, connection_state(S_SENT), socket->read_done); }
static void ftp_get_banner(struct connection *c) { struct read_buffer *rb; set_timeout(c); setcstate(c, S_SENT); if (!(rb = alloc_read_buffer(c))) return; read_from_socket(c, c->sock1, rb, ftp_got_banner); }
static void ftp_logged(struct connection *c) { struct read_buffer *rb; if (!(rb = alloc_read_buffer(c))) return; if (!ftp_options.fast_ftp) { ftp_got_user_info(c, rb); return; } read_from_socket(c, c->sock1, rb, ftp_got_info); }
int32_t destiny_socket_recv(int s, void *buf, uint32_t len, int flags) { /* Variables */ uint8_t read_bytes; msg_t m_recv, m_send; socket_internal_t *current_int_tcp_socket; /* Check if socket exists */ if (!is_tcp_socket(s)) { printf("INFO: NO TCP SOCKET!\n"); return -1; } current_int_tcp_socket = get_socket(s); /* Setting Thread PID */ current_int_tcp_socket->recv_pid = thread_getpid(); if (current_int_tcp_socket->tcp_input_buffer_end > 0) { return read_from_socket(current_int_tcp_socket, buf, len); } msg_receive(&m_recv); if ((exists_socket(s)) && (current_int_tcp_socket->tcp_input_buffer_end > 0)) { read_bytes = read_from_socket(current_int_tcp_socket, buf, len); net_msg_reply(&m_recv, &m_send, UNDEFINED); return read_bytes; } /* Received FIN */ if (m_recv.type == CLOSE_CONN) { /* Sent FIN_ACK, wait for ACK */ msg_receive(&m_recv); /* Received ACK, return with closed socket!*/ return -1; } /* Received Last ACK (connection closed) or no data to read yet */ return -1; }
static int handle_events(v_io_event_t *ev) { v_connection_t *c; int res; v_string_t *data; c = ev->data; switch(c->status) { case V_CONNECTION_READ: if (read_from_socket(c) == V_ERR) { return V_ERR; } if (v_stream_length(c->buf) >= c->read_count) { data = v_stream_read(c->buf, c->read_count); if (data == NULL) { v_close_connection(c); return V_ERR; } return v_method_call(c->read_callback, 1, data); } return v_io_add(c->event, V_IO_READ, handle_events); case V_CONNECTION_READ_UNTIL: if (read_from_socket(c) == V_ERR) { return V_ERR; } res = v_stream_read_until(c->buf, &data, c->read_delimeter.data, c->read_delimeter.len, c->read_until_max); if (res == V_OK) { return v_method_call(c->read_callback, 1, data); } else if (res == V_AGAIN) { return v_io_add(c->event, V_IO_READ, handle_events); } v_close_connection(c); return V_ERR; case V_IO_WRITE: case V_IO_CLOSE: return v_method_call(c->write_callback, 0, NULL); } return V_OK; }
/** * client_manager * * Thread function to manage client connections. * * @param data Thread data for the function */ void* client_manager(void *data) { int nready; client *c = NULL; node *n = NULL; server *s = (server *)data; /* set up as a tcp server */ server_init(s); while (running) { pthread_mutex_lock(&s->dataLock); FD_ZERO(&s->allset); FD_SET(s->listen_sd, &s->allset); /* loop through all possible socket connections and add * them to fd_set */ for (n = s->client_list->link; n != NULL; n = n->next) { c = (client *)n->data; FD_SET(c->fd, &s->allset); if (c->fd > s->maxfd) s->maxfd = c->fd; } /* Monitor sockets for any activity of new connections or data transfer */ nready = select(s->maxfd + 1, &s->allset, NULL, NULL, NULL); pthread_mutex_unlock(&s->dataLock); if (nready < 0) { /* Something interrupted the call, cause EINTR, continue */ if (errno == EINTR) continue; else SystemFatal("Select() Error\n"); } else if (nready == 0) { /* nothing to read, continue */ continue; } else { /* There is an activity on one or more sockets. */ read_from_socket(s); } } fprintf(stdout, "Exiting the client manager\n"); close(s->listen_sd); free(s); pthread_exit(NULL); }
void read_select(struct connection *c) { struct read_buffer *rb; int rd; if (!(rb = c->buffer)) { internal("read socket has no buffer"); setcstate(c, S_INTERNAL); abort_connection(c); return; } set_handlers(rb->sock, NULL, NULL, NULL, NULL); if ((unsigned)rb->len > MAXINT - sizeof(struct read_buffer) - READ_SIZE) overalloc(); rb = mem_realloc(rb, sizeof(struct read_buffer) + rb->len + READ_SIZE); c->buffer = rb; #ifdef HAVE_SSL if(c->ssl) { if ((rd = SSL_read(c->ssl, rb->data + rb->len, READ_SIZE)) <= 0) { int err; if ((err = SSL_get_error(c->ssl, rd)) == SSL_ERROR_WANT_READ) { read_from_socket(c, rb->sock, rb, rb->done); return; } if (rb->close && !rd) { rb->close = 2; rb->done(c, rb); return; } setcstate(c, rd ? (err == SSL_ERROR_SYSCALL ? get_error_from_errno(errno) : S_SSL_ERROR) : S_CANT_READ); /*mem_free(rb);*/ if (!rd || err == SSL_ERROR_SYSCALL) retry_connection(c); else abort_connection(c); return; } } else #endif if ((rd = read(rb->sock, rb->data + rb->len, READ_SIZE)) <= 0) { if (rb->close && !rd) { rb->close = 2; rb->done(c, rb); return; } setcstate(c, rd ? get_error_from_errno(errno) : S_CANT_READ); /*mem_free(rb);*/ retry_connection(c); return; } log_data(rb->data + rb->len, rd); rb->len += rd; rb->done(c, rb); }
static void * slave_thread(void *arg) { struct client_data *from_info; /* identity of connected client */ int bytes_read; /* number of bytes read from socket */ int bytes_written; /* number of bytes written to socket */ char *buffer; /* buffer for socket read/write data */ /* get connection data from argument pointer */ from_info = (struct client_data *)(arg); buffer = (char *)malloc(BUFFER_SIZE); if (buffer == NULL) { fprintf(stderr, "ERROR: cannot allocate memory for buffer\n"); exit(1); } /* end if */ printf("Connection from host %s (%s), port %d.\n", from_info->name, from_info->addr, from_info->port); do { bytes_read = read_from_socket(from_info->sd, buffer, BUFFER_SIZE, 100); if (bytes_read > 0) { bytes_written = write_to_socket(from_info->sd, buffer, bytes_read, 100); } /* end if */ } while (bytes_read > 0); close(from_info->sd); printf("Connection closed for host %s (%s), port %d.\n", from_info->name, from_info->addr, from_info->port); /* * Deallocate memory */ free(buffer); free(from_info); pthread_mutex_lock(&slave_thread_info.mutex); slave_thread_info.num_active--; if (slave_thread_info.num_active == (MAX_NUM_THREADS - 1)) { pthread_cond_signal(&slave_thread_info.thread_exit_cv); } /* end if */ pthread_mutex_unlock(&slave_thread_info.mutex); pthread_exit(NULL); } /* end of slave_thread */
static void get_request(struct connection *conn) { struct read_buffer *rb = alloc_read_buffer(conn->socket); if (!rb) return; memcpy(rb->data, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n", 45); rb->length = 45; rb->freespace -= 45; conn->unrestartable = 1; conn->socket->state = SOCKET_END_ONCLOSE; read_from_socket(conn->socket, rb, connection_state(S_SENT), http_got_header); }
static void read_from_stdin(struct connection *conn) { struct read_buffer *rb = alloc_read_buffer(conn->socket); if (!rb) return; memcpy(rb->data, "HTTP/1.0 200 OK\r\n\r\n", 19); rb->length = 19; rb->freespace -= 19; conn->unrestartable = 1; conn->socket->state = SOCKET_END_ONCLOSE; read_from_socket(conn->socket, rb, connection_state(S_SENT), check_if_closed); }
int main(void) { struct data *d = malloc(sizeof(*d)); struct addrinfo *addrinfo; struct io_listener *l; int fd, status; /* This is how many tests you plan to run */ plan_tests(9); d->state = 0; d->bytes = 1024*1024; d->buf = malloc(d->bytes); memset(d->buf, 'a', d->bytes); fd = make_listen_fd(PORT, &addrinfo); ok1(fd >= 0); l = io_new_listener(fd, init_conn, d); ok1(l); fflush(stdout); if (!fork()) { io_close_listener(l); read_from_socket(d->bytes, addrinfo); freeaddrinfo(addrinfo); free(d->buf); free(d); exit(0); } ok1(io_loop() == d); ok1(d->state == 2); ok1(wait(&status)); ok1(WIFEXITED(status)); ok1(WEXITSTATUS(status) == 0); freeaddrinfo(addrinfo); free(d->buf); free(d); io_close_listener(l); /* This exits depending on whether all tests passed */ return exit_status(); }
char* send_proc_to_local_server(struct proc_process p) { struct sockaddr_un them; int sender = socket(AF_UNIX, SOCK_STREAM, 0); if (sender < 0) { printf("Error creating connection to server\n"); return NULL; } them.sun_family = AF_UNIX; strcpy(them.sun_path,LOCAL_SERVER_SOCK); if (connect(sender,(struct sockaddr *)&them,sizeof(them)) < 0) { printf("Error connecting to server\n"); return NULL; } unsigned char type = 's'; write_to_socket(&sender,&type,sizeof(char)); write_process(p,&sender,write_to_socket); char* id = malloc(SIZE_OF_ID*sizeof(char));; read_from_socket(&sender,id,SIZE_OF_ID*sizeof(char)); return id; }
int main(int argc, char *argv[] ){ int listenfd = 0, connfd = 0; struct sockaddr_in serv_addr; char sendBuff[5000]; time_t ticks; listenfd = socket(AF_INET, SOCK_STREAM, 0); memset(&serv_addr, '0', sizeof(serv_addr)); memset(sendBuff, '0', sizeof(sendBuff)); serv_addr.sin_family = AF_INET; // should be always set to this serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //ip addr of a host server serv_addr.sin_port = htons(5000); // Port number bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); listen(listenfd, 10); while(1){ connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); if(connfd < 0) { error("Error in server."); } ticks = time(NULL); // what is this snprintf(sendBuff, sizeof(sendBuff), "This is SigUMT server. Commands: send \n"); write(connfd, sendBuff, strlen(sendBuff)); char* ptr = malloc(15); read_from_socket(connfd, ptr); close(connfd); sleep(1); } }
static void finger_get_response(struct connection *c, struct read_buffer *rb) { int l; int a; set_timeout(c); if (!c->cache) { if (get_cache_entry(c->url, &c->cache)) { setcstate(c, S_OUT_OF_MEM); abort_connection(c); return; } c->cache->refcount--; } if (rb->close == 2) { finger_end_request(c, S__OK); return; } l = rb->len; if ((off_t)(0UL + c->from + l) < 0) { setcstate(c, S_LARGE_FILE); abort_connection(c); return; } c->received += l; a = add_fragment(c->cache, c->from, rb->data, l); if (a < 0) { setcstate(c, a); abort_connection(c); return; } if (a == 1) c->tries = 0; c->from += l; kill_buffer_data(rb, l); read_from_socket(c, c->sock1, rb, finger_get_response); setcstate(c, S_TRANS); }
void read_http_data(struct connection *c, struct read_buffer *rb) { struct http_connection_info *info = c->info; set_timeout(c); if (rb->close == 2) { setcstate(c, S_OK); http_end_request(c, 0); return; } if (info->length != -2) { int l = rb->len; if (info->length >= 0 && info->length < l) l = info->length; if (c->from + l < 0) { setcstate(c, S_LARGE_FILE); abort_connection(c); return; } c->received += l; if (add_fragment(c->cache, c->from, rb->data, l) == 1) c->tries = 0; if (info->length >= 0) info->length -= l; c->from += l; kill_buffer_data(rb, l); if (!info->length && !rb->close) { setcstate(c, S_OK); http_end_request(c, 0); return; } } else { next_chunk: if (info->chunk_remaining == -2) { int l; if ((l = is_line_in_buffer(rb))) { if (l == -1) { setcstate(c, S_HTTP_ERROR); abort_connection(c); return; } kill_buffer_data(rb, l); if (l <= 2) { setcstate(c, S_OK); http_end_request(c, 0); return; } goto next_chunk; } } else if (info->chunk_remaining == -1) { int l; if ((l = is_line_in_buffer(rb))) { unsigned char *de; long n = 0; /* warning, go away */ if (l != -1) n = strtol(rb->data, (char **)(void *)&de, 16); if (l == -1 || n < 0 || n >= MAXINT || de == rb->data) { setcstate(c, S_HTTP_ERROR); abort_connection(c); return; } kill_buffer_data(rb, l); if (!(info->chunk_remaining = n)) info->chunk_remaining = -2; goto next_chunk; } } else { int l = info->chunk_remaining; if (l > rb->len) l = rb->len; if (c->from + l < 0) { setcstate(c, S_LARGE_FILE); abort_connection(c); return; } c->received += l; if (add_fragment(c->cache, c->from, rb->data, l) == 1) c->tries = 0; info->chunk_remaining -= l; c->from += l; kill_buffer_data(rb, l); if (!info->chunk_remaining && rb->len >= 1) { if (rb->data[0] == 10) kill_buffer_data(rb, 1); else { if (rb->data[0] != 13 || (rb->len >= 2 && rb->data[1] != 10)) { setcstate(c, S_HTTP_ERROR); abort_connection(c); return; } if (rb->len < 2) goto read_more; kill_buffer_data(rb, 2); } info->chunk_remaining = -1; goto next_chunk; } } } read_more: read_from_socket(c, c->sock1, rb, read_http_data); setcstate(c, S_TRANS); }
void smb_protocol_handler(struct connection *conn) { int smb_pipe[2] = { -1, -1 }; int header_pipe[2] = { -1, -1 }; pid_t cpid; if (c_pipe(smb_pipe) || c_pipe(header_pipe)) { int s_errno = errno; if (smb_pipe[0] >= 0) close(smb_pipe[0]); if (smb_pipe[1] >= 0) close(smb_pipe[1]); if (header_pipe[0] >= 0) close(header_pipe[0]); if (header_pipe[1] >= 0) close(header_pipe[1]); abort_connection(conn, connection_state_for_errno(s_errno)); return; } conn->from = 0; conn->unrestartable = 1; find_auth(conn->uri); /* remember username and password */ cpid = fork(); if (cpid == -1) { int s_errno = errno; close(smb_pipe[0]); close(smb_pipe[1]); close(header_pipe[0]); close(header_pipe[1]); retry_connection(conn, connection_state_for_errno(s_errno)); return; } if (!cpid) { dup2(open("/dev/null", O_RDONLY), 0); close(1); close(2); data_out = fdopen(smb_pipe[1], "w"); header_out = fdopen(header_pipe[1], "w"); if (!data_out || !header_out) exit(1); close(smb_pipe[0]); close(header_pipe[0]); /* There may be outgoing data in stdio buffers * inherited from the parent process. The parent * process is going to write this data, so the child * process must not do that. Closing the file * descriptors ensures this. * * FIXME: If something opens more files and gets the * same file descriptors and does not close them * before exit(), then stdio may attempt to write the * buffers to the wrong files. This might happen for * example if libsmbclient calls syslog(). */ close_all_fds_but_two(smb_pipe[1], header_pipe[1]); do_smb(conn); } else { struct read_buffer *buf2; conn->data_socket->fd = smb_pipe[0]; conn->socket->fd = header_pipe[0]; set_nonblocking_fd(conn->data_socket->fd); set_nonblocking_fd(conn->socket->fd); close(smb_pipe[1]); close(header_pipe[1]); buf2 = alloc_read_buffer(conn->socket); if (!buf2) { close_socket(conn->data_socket); close_socket(conn->socket); abort_connection(conn, connection_state(S_OUT_OF_MEM)); return; } read_from_socket(conn->socket, buf2, connection_state(S_CONN), smb_got_header); } }
static void smb_got_header(struct socket *socket, struct read_buffer *rb) { struct connection *conn = socket->conn; struct read_buffer *buf; int error = 0; conn->cached = get_cache_entry(conn->uri); if (!conn->cached) { /* Even though these are pipes rather than real * sockets, call close_socket instead of close, to * ensure that abort_connection won't try to close the * file descriptors again. (Could we skip the calls * and assume abort_connection will do them?) */ close_socket(socket); close_socket(conn->data_socket); abort_connection(conn, connection_state(S_OUT_OF_MEM)); return; } socket->state = SOCKET_END_ONCLOSE; if (rb->length > 0) { unsigned char *ctype = memacpy(rb->data, rb->length); if (ctype && *ctype) { if (!strcmp(ctype, "text/x-error")) { error = 1; mem_free(ctype); } else { if (ctype[0] >= '0' && ctype[0] <= '9') { #ifdef HAVE_ATOLL conn->est_length = (off_t)atoll(ctype); #else conn->est_length = (off_t)atol(ctype); #endif mem_free(ctype); /* avoid error */ if (!conn->est_length) { abort_connection(conn, connection_state(S_OK)); return; } } else mem_free_set(&conn->cached->content_type, ctype); } } else { mem_free_if(ctype); } } buf = alloc_read_buffer(conn->data_socket); if (!buf) { close_socket(socket); close_socket(conn->data_socket); abort_connection(conn, connection_state(S_OUT_OF_MEM)); return; } if (error) { mem_free_set(&conn->cached->content_type, stracpy("text/html")); read_from_socket(conn->data_socket, buf, connection_state(S_CONN), smb_got_error); } else { read_from_socket(conn->data_socket, buf, connection_state(S_CONN), smb_got_data); } }
void http_got_header(struct connection *c, struct read_buffer *rb) { int cf; int state = c->state != S_PROC ? S_GETH : S_PROC; unsigned char *head; unsigned char *cookie, *ch; int a, h, version; unsigned char *d; struct cache_entry *e; struct http_connection_info *info; unsigned char *host = upcase(c->url[0]) != 'P' ? c->url : get_url_data(c->url); set_timeout(c); info = c->info; if (rb->close == 2) { unsigned char *h; if (!c->tries && (h = get_host_name(host))) { if (info->bl_flags & BL_NO_CHARSET) { del_blacklist_entry(h, BL_NO_CHARSET); } else { add_blacklist_entry(h, BL_NO_CHARSET); c->tries = -1; } mem_free(h); } setcstate(c, S_CANT_READ); retry_connection(c); return; } rb->close = 0; again: if ((a = get_header(rb)) == -1) { setcstate(c, S_HTTP_ERROR); abort_connection(c); return; } if (!a) { read_from_socket(c, c->sock1, rb, http_got_header); setcstate(c, state); return; } if (a != -2) { head = mem_alloc(a + 1); memcpy(head, rb->data, a); head[a] = 0; kill_buffer_data(rb, a); } else { head = stracpy("HTTP/0.9 200 OK\r\nContent-Type: text/html\r\n\r\n"); } if (get_http_code(head, &h, &version) || h == 101) { mem_free(head); setcstate(c, S_HTTP_ERROR); abort_connection(c); return; } if (check_http_server_bugs(host, c->info, head) && is_connection_restartable(c)) { mem_free(head); setcstate(c, S_RESTART); retry_connection(c); return; } ch = head; while ((cookie = parse_http_header(ch, "Set-Cookie", &ch))) { unsigned char *host = upcase(c->url[0]) != 'P' ? c->url : get_url_data(c->url); set_cookie(NULL, host, cookie); mem_free(cookie); } if (h == 100) { mem_free(head); state = S_PROC; goto again; } if (h < 200) { mem_free(head); setcstate(c, S_HTTP_ERROR); abort_connection(c); return; } if (h == 204) { mem_free(head); setcstate(c, S_HTTP_204); http_end_request(c, 0); return; } if (h == 304) { mem_free(head); setcstate(c, S_OK); http_end_request(c, 1); return; } if ((h == 500 || h == 502 || h == 503 || h == 504) && http_bugs.retry_internal_errors && is_connection_restartable(c)) { /* !!! FIXME: wait some time ... */ mem_free(head); setcstate(c, S_RESTART); retry_connection(c); return; } if (!c->cache && get_cache_entry(c->url, &c->cache)) { mem_free(head); setcstate(c, S_OUT_OF_MEM); abort_connection(c); return; } e = c->cache; e->http_code = h; if (e->head) mem_free(e->head); e->head = head; if ((d = parse_http_header(head, "Expires", NULL))) { time_t t = parse_http_date(d); if (t && e->expire_time != 1) e->expire_time = t; mem_free(d); } if ((d = parse_http_header(head, "Pragma", NULL))) { if (!casecmp(d, "no-cache", 8)) e->expire_time = 1; mem_free(d); } if ((d = parse_http_header(head, "Cache-Control", NULL))) { char *f = d; while (1) { while (*f && (*f == ' ' || *f == ',')) f++; if (!*f) break; if (!casecmp(f, "no-cache", 8) || !casecmp(f, "must-revalidate", 15)) { e->expire_time = 1; } if (!casecmp(f, "max-age=", 8)) { if (e->expire_time != 1) e->expire_time = time(NULL) + atoi(f + 8); } while (*f && *f != ',') f++; } mem_free(d); } #ifdef HAVE_SSL if (c->ssl) { int l = 0; if (e->ssl_info) mem_free(e->ssl_info); e->ssl_info = init_str(); add_num_to_str(&e->ssl_info, &l, SSL_get_cipher_bits(c->ssl, NULL)); add_to_str(&e->ssl_info, &l, "-bit "); add_to_str(&e->ssl_info, &l, SSL_get_cipher_version(c->ssl)); add_to_str(&e->ssl_info, &l, " "); add_to_str(&e->ssl_info, &l, (unsigned char *)SSL_get_cipher_name(c->ssl)); } #endif if (e->redirect) mem_free(e->redirect), e->redirect = NULL; if (h == 301 || h == 302 || h == 303 || h == 307) { if ((h == 302 || h == 307) && !e->expire_time) e->expire_time = 1; if ((d = parse_http_header(e->head, "Location", NULL))) { unsigned char *user, *ins; unsigned char *newuser, *newpassword; if (!parse_url(d, NULL, &user, NULL, NULL, NULL, &ins, NULL, NULL, NULL, NULL, NULL, NULL) && !user && ins && (newuser = get_user_name(host))) { if (*newuser) { int ins_off = ins - d; newpassword = get_pass(host); if (!newpassword) newpassword = stracpy(""); add_to_strn(&newuser, ":"); add_to_strn(&newuser, newpassword); add_to_strn(&newuser, "@"); extend_str(&d, strlen(newuser)); ins = d + ins_off; memmove(ins + strlen(newuser), ins, strlen(ins) + 1); memcpy(ins, newuser, strlen(newuser)); mem_free(newpassword); } mem_free(newuser); } if (e->redirect) mem_free(e->redirect); e->redirect = d; e->redirect_get = h == 303; } } if (!e->expire_time && strchr(c->url, POST_CHAR)) e->expire_time = 1; info->close = 0; info->length = -1; info->version = version; if ((d = parse_http_header(e->head, "Connection", NULL)) || (d = parse_http_header(e->head, "Proxy-Connection", NULL))) { if (!strcasecmp(d, "close")) info->close = 1; mem_free(d); } else if (version < 11) info->close = 1; cf = c->from; c->from = 0; if ((d = parse_http_header(e->head, "Content-Range", NULL))) { if (strlen(d) > 6) { d[5] = 0; if (!(strcasecmp(d, "bytes")) && d[6] >= '0' && d[6] <= '9') { #if defined(HAVE_STRTOLL) long long f = strtoll(d + 6, NULL, 10); #elif defined(HAVE_STRTOQ) longlong f = strtoq(d + 6, NULL, 10); #else long f = strtol(d + 6, NULL, 10); if (f == MAXLONG) f = -1; #endif if (f >= 0 && (off_t)f >= 0 && (off_t)f == f) c->from = f; } } mem_free(d); } if (cf && !c->from && !c->unrestartable) c->unrestartable = 1; if (c->from > cf || c->from < 0) { setcstate(c, S_HTTP_ERROR); abort_connection(c); return; } if ((d = parse_http_header(e->head, "Content-Length", NULL))) { unsigned char *ep; #if defined(HAVE_STRTOLL) long long l = strtoll(d, (char **)(void *)&ep, 10); #elif defined(HAVE_STRTOQ) longlong l = strtoq(d, (char **)(void *)&ep, 10); #else long l = strtol(d, (char **)(void *)&ep, 10); if (l == MAXLONG) l = -1; #endif if (!*ep && l >= 0 && (off_t)l >= 0 && (off_t)l == l) { if (!info->close || version >= 11) info->length = l; if (c->from + l >= 0) c->est_length = c->from + l; } mem_free(d); } if ((d = parse_http_header(e->head, "Accept-Ranges", NULL))) { if (!strcasecmp(d, "none") && !c->unrestartable) c->unrestartable = 1; mem_free(d); } else { if (!c->unrestartable && !c->from) c->unrestartable = 1; } if (info->bl_flags & BL_NO_RANGE && !c->unrestartable) c->unrestartable = 1; if ((d = parse_http_header(e->head, "Transfer-Encoding", NULL))) { if (!strcasecmp(d, "chunked")) { info->length = -2; info->chunk_remaining = -1; } mem_free(d); } if (!info->close && info->length == -1) info->close = 1; if ((d = parse_http_header(e->head, "Last-Modified", NULL))) { if (e->last_modified && strcasecmp(e->last_modified, d)) { delete_entry_content(e); if (c->from) { c->from = 0; mem_free(d); setcstate(c, S_MODIFIED); retry_connection(c); return; } } if (!e->last_modified) e->last_modified = d; else mem_free(d); } if (!e->last_modified && (d = parse_http_header(e->head, "Date", NULL))) e->last_modified = d; if (info->length == -1 || (version < 11 && info->close)) rb->close = 1; read_http_data(c, rb); }
int main(int argc, const char **argv) { unsigned char proxy_header[MAX_HEADER_SIZE + 1]; ssize_t n = 0; int address_len = 0; if (argc == 1) n = read(STDIN_FILENO, proxy_header, MAX_HEADER_SIZE); else if (argc == 2) n = read_from_socket(argv[1], proxy_header, MAX_HEADER_SIZE); else { fprintf(stderr, "Usage: parse_proxy_v2 [port]\n"); return (1); } if (n < 16) { printf("ERROR:\tread too few bytes.\n"); return (1); } proxy_header[n] = '\0'; if (strncmp("PROXY TCP", (char *)proxy_header, 9) == 0) { /* PROXY version 1 over TCP */ fprintf(stdout, "ERROR:\tPROXY v1 parsing not supported in this tool.\n"); return (1); } else if (memcmp(PROXY_V2_HEADER, proxy_header, 12) != 0) { printf("ERROR:\tNot a valid PROXY header\n"); return (1); } printf("PROXY v2 detected.\n"); switch (proxy_header[12]) { case 0x20: printf("ERROR:\tLOCAL connection\n"); return (1); case 0x21: printf("Connection:\tPROXYed connection detected\n"); break; default: printf("ERROR:\t13th byte has illegal value %d\n", (int)proxy_header[12]); return (1); } switch (proxy_header[13]) { case 0x00: printf("ERROR:\tProtocol:\tUnspecified/unsupported\n"); return (1); case 0x11: printf("Protocol:\tTCP over IPv4\n"); address_len = 12; break; case 0x12: printf("Protocol:\tUDP over IPv4\n"); printf("ERROR:\tProtocol unsupported in hitch seen\n"); address_len = 12; break; case 0x21: printf("Protocol:\tTCP over IPv6\n"); address_len = 36; break; case 0x22: printf("Protocol:\tUDP over IPv6\n"); printf("ERROR:\tProtocol unsupported in hitch\n"); address_len = 36; break; case 0x31: printf("Protocol:\tUNIX stream\n"); address_len = 216; break; case 0x32: printf("Protocol:\tUNIX datagram\n"); printf("ERROR:\tProtocol unsupported in hitch\n"); address_len = 216; break; default: printf("ERROR:\t14th byte has illegal value %d\n", (int)proxy_header[13]); return (1); } int additional_len = (proxy_header[14] << 8) + proxy_header[15]; if (additional_len < address_len) { printf("ERROR:\tThe the total header length %d does" " not leave room for the addresses\n", additional_len + 16); return (1); } if (additional_len + 16 > n) { printf("ERROR:\tToo few bytes was read; %zd\n", n); return (1); } if (address_len == 12) print_addr_with_ports(AF_INET, 4, proxy_header + 16); else if (address_len == 36) print_addr_with_ports(AF_INET6, 16, proxy_header + 16); else { printf("ERROR:\tPrinting of UNIX socket addresses" " not implemented.\n"); } if (address_len < additional_len) return print_extensions(proxy_header + 16 + address_len, additional_len - address_len); return (0); }