long vnc_client_read_ws(VncState *vs) { int ret, err; uint8_t *payload; size_t payload_size, frame_size; VNC_DEBUG("Read websocket %p size %zd offset %zd\n", vs->ws_input.buffer, vs->ws_input.capacity, vs->ws_input.offset); buffer_reserve(&vs->ws_input, 4096); ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), 4096); if (!ret) { return 0; } vs->ws_input.offset += ret; /* make sure that nothing is left in the ws_input buffer */ do { err = vncws_decode_frame(&vs->ws_input, &payload, &payload_size, &frame_size); if (err <= 0) { return err; } buffer_reserve(&vs->input, payload_size); buffer_append(&vs->input, payload, payload_size); buffer_advance(&vs->ws_input, frame_size); } while (vs->ws_input.offset > 0); return ret; }
long vnc_client_read_ws(VncState *vs) { int ret, err; uint8_t *payload; size_t payload_size, header_size; VNC_DEBUG("Read websocket %p size %zd offset %zd\n", vs->ws_input.buffer, vs->ws_input.capacity, vs->ws_input.offset); buffer_reserve(&vs->ws_input, 4096); ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), 4096); if (!ret) { return 0; } vs->ws_input.offset += ret; ret = 0; /* consume as much of ws_input buffer as possible */ do { if (vs->ws_payload_remain == 0) { err = vncws_decode_frame_header(&vs->ws_input, &header_size, &vs->ws_payload_remain, &vs->ws_payload_mask); if (err <= 0) { return err; } buffer_advance(&vs->ws_input, header_size); } if (vs->ws_payload_remain != 0) { err = vncws_decode_frame_payload(&vs->ws_input, &vs->ws_payload_remain, &vs->ws_payload_mask, &payload, &payload_size); if (err < 0) { return err; } if (err == 0) { return ret; } ret += err; buffer_reserve(&vs->input, payload_size); buffer_append(&vs->input, payload, payload_size); buffer_advance(&vs->ws_input, payload_size); } } while (vs->ws_input.offset > 0); return ret; }
static void write_string(struct buffer *b, const char *key, size_t sz) { buffer_reserve(b,sz+1); memcpy(b->ptr + b->size, key, sz); b->ptr[b->size+sz] = '\0'; b->size+=sz+1; }
static inline int reserve_length(struct buffer *b) { int sz = b->size; buffer_reserve(b,4); b->size +=4; return sz; }
static void crystal_exchange(struct crystal *p, uint send_n, uint targ, int recvn, int tag) { comm_req req[3]; uint count[2] = {0,0}, sum, *recv[2]; if(recvn) comm_irecv(&req[1],&p->comm, &count[0],sizeof(uint), targ ,tag); if(recvn==2) comm_irecv(&req[2],&p->comm, &count[1],sizeof(uint), p->comm.id-1,tag); comm_isend(&req[0],&p->comm, &send_n,sizeof(uint), targ,tag); comm_wait(req,recvn+1); sum = p->data.n + count[0] + count[1]; buffer_reserve(&p->data,sum*sizeof(uint)); recv[0] = (uint*)p->data.ptr + p->data.n, recv[1] = recv[0] + count[0]; p->data.n = sum; if(recvn) comm_irecv(&req[1],&p->comm, recv[0],count[0]*sizeof(uint), targ ,tag+1); if(recvn==2) comm_irecv(&req[2],&p->comm, recv[1],count[1]*sizeof(uint), p->comm.id-1,tag+1); comm_isend(&req[0],&p->comm, p->work.ptr,send_n*sizeof(uint), targ,tag+1); comm_wait(req,recvn+1); }
void vncws_encode_frame(Buffer *output, const void *payload, const size_t payload_size) { size_t header_size = 0; unsigned char opcode = WS_OPCODE_BINARY_FRAME; union { char buf[WS_HEAD_MAX_LEN]; WsHeader ws; } header; if (!payload_size) { return; } header.ws.b0 = 0x80 | (opcode & 0x0f); if (payload_size <= 125) { header.ws.b1 = (uint8_t)payload_size; header_size = 2; } else if (payload_size < 65536) { header.ws.b1 = 0x7e; header.ws.u.s16.l16 = cpu_to_be16((uint16_t)payload_size); header_size = 4; } else { header.ws.b1 = 0x7f; header.ws.u.s64.l64 = cpu_to_be64(payload_size); header_size = 10; } buffer_reserve(output, header_size + payload_size); buffer_append(output, header.buf, header_size); buffer_append(output, payload, payload_size); }
static int qio_channel_websock_handshake_send_response(QIOChannelWebsock *ioc, const char *key, Error **errp) { char combined_key[QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN + QIO_CHANNEL_WEBSOCK_GUID_LEN + 1]; char *accept = NULL, *response = NULL; size_t responselen; g_strlcpy(combined_key, key, QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN + 1); g_strlcat(combined_key, QIO_CHANNEL_WEBSOCK_GUID, QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN + QIO_CHANNEL_WEBSOCK_GUID_LEN + 1); /* hash and encode it */ if (qcrypto_hash_base64(QCRYPTO_HASH_ALG_SHA1, combined_key, QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN + QIO_CHANNEL_WEBSOCK_GUID_LEN, &accept, errp) < 0) { return -1; } response = g_strdup_printf(QIO_CHANNEL_WEBSOCK_HANDSHAKE_RESPONSE, accept); responselen = strlen(response); buffer_reserve(&ioc->encoutput, responselen); buffer_append(&ioc->encoutput, response, responselen); g_free(accept); g_free(response); return 0; }
int buffer_printf(buffer_type *buffer, const char *format, ...) { va_list args; int written; size_t remaining; buffer_invariant(buffer); assert(buffer->_limit == buffer->_capacity); remaining = buffer_remaining(buffer); va_start(args, format); written = vsnprintf((char *) buffer_current(buffer), remaining, format, args); va_end(args); if (written >= 0 && (size_t) written >= remaining) { buffer_reserve(buffer, written + 1); va_start(args, format); written = vsnprintf((char *) buffer_current(buffer), buffer_remaining(buffer), format, args); va_end(args); } buffer->_position += written; return written; }
/* * Reads a whole file into a buffer. Returns a NULL buffer and sets errno on * error. */ static struct buffer read_file(FILE* fp) { struct buffer ret; BUFFER_INIT_(&ret); size_t bytes_read; do { if(buffer_reserve(&ret, ret.len + CHUNK_SIZE)) { errno = NBT_EMEM; goto err; } bytes_read = fread(ret.data + ret.len, 1, CHUNK_SIZE, fp); ret.len += bytes_read; if(ferror(fp)) { errno = NBT_EIO; goto err; } } while(!feof(fp)); return ret; err: buffer_free(&ret); BUFFER_INIT_(&ret); return ret; }
void sarray_permute_buf_(size_t align, size_t size, void *A, size_t n, buffer *buf) { buffer_reserve(buf,align_as_(align,n*sizeof(uint)+size)); sarray_permute_(size,A,n, buf->ptr, (char*)buf->ptr + align_as_(align,n*sizeof(uint))); }
static void text_term_client_read(void *opaque) { struct TextTermClientState *tcs = opaque; long ret; buffer_reserve(&tcs->input, 4096); ret = recv(tcs->csock, buffer_end(&tcs->input), 4096, 0); ret = text_term_client_io_error(tcs, ret, socket_error()); if (ret <= 0) return; tcs->input.offset += ret; while (tcs->input.offset > 0) { ssize_t ret = write(tcs->ts->ssock, tcs->input.buffer, tcs->input.offset); if (ret > 0) { if (ret != tcs->input.offset) { memmove(tcs->input.buffer, tcs->input.buffer + ret, tcs->input.offset - ret); } tcs->input.offset -= ret; } else { text_term_client_io_error(tcs, ret, socket_error()); return; } } }
void vncws_handshake_read(void *opaque) { VncState *vs = opaque; uint8_t *handshake_end; long ret; buffer_reserve(&vs->ws_input, 4096); ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), 4096); if (!ret) { if (vs->csock == -1) { vnc_disconnect_finish(vs); } return; } vs->ws_input.offset += ret; handshake_end = (uint8_t *)g_strstr_len((char *)vs->ws_input.buffer, vs->ws_input.offset, WS_HANDSHAKE_END); if (handshake_end) { qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs); vncws_process_handshake(vs, vs->ws_input.buffer, vs->ws_input.offset); buffer_advance(&vs->ws_input, handshake_end - vs->ws_input.buffer + strlen(WS_HANDSHAKE_END)); } }
void vncws_handshake_read(void *opaque) { VncState *vs = opaque; uint8_t *handshake_end; long ret; /* Typical HTTP headers from novnc are 512 bytes, so limiting * total header size to 4096 is easily enough. */ size_t want = 4096 - vs->ws_input.offset; buffer_reserve(&vs->ws_input, want); ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), want); if (!ret) { if (vs->csock == -1) { vnc_disconnect_finish(vs); } return; } vs->ws_input.offset += ret; handshake_end = (uint8_t *)g_strstr_len((char *)vs->ws_input.buffer, vs->ws_input.offset, WS_HANDSHAKE_END); if (handshake_end) { qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs); vncws_process_handshake(vs, vs->ws_input.buffer, vs->ws_input.offset); buffer_advance(&vs->ws_input, handshake_end - vs->ws_input.buffer + strlen(WS_HANDSHAKE_END)); } else if (vs->ws_input.offset >= 4096) { VNC_DEBUG("End of headers not found in first 4096 bytes\n"); vnc_client_error(vs); } }
/* * Reads a whole file into a buffer. Returns a NULL buffer and sets errno on * error. */ static struct buffer read_file(FILE* fp) { struct buffer ret = BUFFER_INIT; size_t bytes_read; do { if(buffer_reserve(&ret, ret.len + CHUNK_SIZE)) { buffer empty = BUFFER_INIT; return (errno = NBT_EMEM), buffer_free(&ret), empty; } bytes_read = fread(ret.data + ret.len, 1, CHUNK_SIZE, fp); ret.len += bytes_read; if(ferror(fp)) { buffer empty = BUFFER_INIT; return (errno = NBT_EIO), buffer_free(&ret), empty; } } while(!feof(fp)); return ret; }
bool buffer_put(Buffer *buf, const void *data, size_t len) { if (!buffer_reserve(buf, len)) return false; memmove(buf->data, data, len); buf->len = len; return true; }
static void marshal_acl(struct buffer* b, acl_options_t* acl) { buffer_reserve(b, sizeof(*acl)); buffer_write(b, acl, sizeof(*acl)); marshal_str(b, acl->ip_address_spec); marshal_str(b, acl->key_name); }
void buffer_insert(buffer *b, size_t position, void *data, size_t size) { buffer_reserve(b, b->size + size); if (position < b->size) memmove((char *) b->data + position + size, (char *) b->data + position, b->size - position); memcpy((char *) b->data + position, data, size); b->size += size; }
void transfer(int dynamic, tuple_list *tl, unsigned pf, crystal_data *crystal) { const unsigned mi=tl->mi,ml=tl->ml,mr=tl->mr; const unsigned tsize = (mi-1) + ml*UINT_PER_LONG + mr*UINT_PER_REAL; sint p, lp = -1; sint *ri; slong *rl; real *rr; uint i, j, *buf, *len=0, *buf_end; /* sort to group by target proc */ tuple_list_sort(tl,pf,&crystal->all->buf); /* pack into buffer for crystal router */ buffer_reserve(&crystal->all->buf,(tl->n*(3+tsize))*sizeof(uint)); crystal->all->n=0, buf = crystal->all->buf.ptr; ri=tl->vi,rl=tl->vl,rr=tl->vr; for(i=tl->n;i;--i) { p = ri[pf]; if(p!=lp) { lp = p; *buf++ = p; /* target */ *buf++ = crystal->id; /* source */ len = buf++; *len=0; /* length */ crystal->all->n += 3; } for(j=0;j<mi;++j,++ri) if(j!=pf) *buf++ = *ri; for(j=ml;j;--j,++rl) memcpy(buf,rl,sizeof(slong)), buf+=UINT_PER_LONG; for(j=mr;j;--j,++rr) memcpy(buf,rr,sizeof(real )), buf+=UINT_PER_REAL; *len += tsize, crystal->all->n += tsize; } crystal_router(crystal); /* unpack */ buf = crystal->all->buf.ptr, buf_end = buf + crystal->all->n; tl->n = 0; ri=tl->vi,rl=tl->vl,rr=tl->vr; while(buf != buf_end) { sint p, len; buf++; /* target ( == this proc ) */ p = *buf++; /* source */ len = *buf++; /* length */ while(len>0) { if(tl->n==tl->max) { if(!dynamic) { tl->n = tl->max + 1; return; } tuple_list_grow(tl); ri = tl->vi + mi*tl->n, rl = tl->vl + ml*tl->n, rr = tl->vr + mr*tl->n; } ++tl->n; for(j=0;j<mi;++j) if(j!=pf) *ri++ = *buf++; else *ri++ = p; for(j=ml;j;--j) memcpy(rl++,buf,sizeof(slong)), buf+=UINT_PER_LONG; for(j=mr;j;--j) memcpy(rr++,buf,sizeof(real )), buf+=UINT_PER_REAL; len-=tsize; } } }
static void read_cb(int fd, int mask, void* user) { int fork_id = (int)user; fork_state* fs = get_fork(fork_id); assert(fd == fs->to_host_fd[0]); fs->has_yielded_reader = 0; if (mask & STD2_CALLBACK_ABORT) { assert(!"abort not implemented"); abort(); return; } buffer_reserve(&fs->in_buffer, 1024); int closed = read_buffer_append(fd, &fs->in_buffer, 1); /* If fd was closed, abort all returns. */ if (closed) { request* req; for (req = fs->first_request; req; req = req->next) std2_abort_return(req->return_id); return; } /* fd wasn't closed so yield new read callback. */ yield_callbacks(fork_id); if (!fs->return_processed) return; fprintf(stderr, "NAH\n"); if (buffer_avail(&fs->in_buffer) < 8) return; int ret_id = *(std2_int32*)buffer_cursor(&fs->in_buffer); int ret_size = *((std2_int32*)buffer_cursor(&fs->in_buffer) + 1); if (buffer_avail(&fs->in_buffer) < 8 + ret_size) return; fprintf(stderr, "std2: got return from fork, id %d, size %d\n", ret_id, ret_size); request* req; for (req = fs->first_request; req; req = req->next) if (req->id == ret_id) { fs->return_processed = 0; std2_continue_return(req->return_id, return_func, req); return; } fprintf(stderr, "std2: bad request id\n"); }
static inline void write_int32(struct buffer *b, int32_t v) { uint32_t uv = (uint32_t)v; buffer_reserve(b,4); b->ptr[b->size++] = uv & 0xff; b->ptr[b->size++] = (uv >> 8)&0xff; b->ptr[b->size++] = (uv >> 16)&0xff; b->ptr[b->size++] = (uv >> 24)&0xff; }
static void text_term_write(struct TextTermClientState *tcs, const void *data, size_t len) { buffer_reserve(&tcs->output, len); text_term_write_pending(tcs); buffer_append(&tcs->output, data, len); }
void sparse_cholesky_factor(uint n, const uint *Arp, const uint *Aj, const real *A, sparse_cholesky_data *out, buffer *buf) { const uint n_uints_as_reals = (n*sizeof(uint)+sizeof(real)-1)/sizeof(real); buffer_reserve(buf,umax_2(4*n*sizeof(uint), (n_uints_as_reals+n)*sizeof(real))); factor_symbolic(n,Arp,Aj,out,buf->ptr); factor_numeric(n,Arp,Aj,A,out,buf->ptr,n_uints_as_reals+(real*)buf->ptr); }
static ssize_t qio_channel_websock_writev(QIOChannel *ioc, const struct iovec *iov, size_t niov, int *fds, size_t nfds, Error **errp) { QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc); size_t i; ssize_t done = 0; ssize_t ret; if (wioc->io_err) { *errp = error_copy(wioc->io_err); return -1; } if (wioc->io_eof) { error_setg(errp, "%s", "Broken pipe"); return -1; } for (i = 0; i < niov; i++) { size_t want = iov[i].iov_len; if ((want + wioc->rawoutput.offset) > QIO_CHANNEL_WEBSOCK_MAX_BUFFER) { want = (QIO_CHANNEL_WEBSOCK_MAX_BUFFER - wioc->rawoutput.offset); } if (want == 0) { goto done; } buffer_reserve(&wioc->rawoutput, want); buffer_append(&wioc->rawoutput, iov[i].iov_base, want); done += want; if (want < iov[i].iov_len) { break; } } done: ret = qio_channel_websock_write_wire(wioc, errp); if (ret < 0 && ret != QIO_CHANNEL_ERR_BLOCK) { qio_channel_websock_unset_watch(wioc); return -1; } qio_channel_websock_set_watch(wioc); if (done == 0) { return QIO_CHANNEL_ERR_BLOCK; } return done; }
static void marshal_str(struct buffer* b, const char* s) { if(!s) marshal_u8(b, 0); else { size_t len = strlen(s); marshal_u8(b, 1); buffer_reserve(b, len+1); buffer_write(b, s, len+1); } }
static int buffer_write (char ** buffer, uint64_t * buffer_size ,uint64_t * buffer_offset ,const void * data, uint64_t size, uint64_t max_size ) { if (!buffer_reserve(buffer, buffer_size, buffer_offset, size, max_size)) return 0; memcpy (*buffer + *buffer_offset, data, size); *buffer_offset += size; return 1; }
void buffer_insert_fill(buffer *b, size_t position, size_t count, void *data, size_t size) { size_t i; buffer_reserve(b, b->size + (count * size)); if (position < b->size) memmove((char *) b->data + position + (count * size), (char *) b->data + position, b->size - position); for (i = 0; i < count; i ++) memcpy((char *) b->data + position + (i * size), data, size); b->size += count * size; }
int buffer_insert(buffer *b, size_t position, char *data, size_t size) { int e; e = buffer_reserve(b, b->size + size); if (e == -1) return -1; if (position < b->size) memmove(b->data + position + size, b->data + position, b->size - position); memcpy(b->data + position, data, size); b->size += size; return 0; }
int buffer_append(struct buffer* b, const void* data, size_t n) { assert(b); if(unlikely(b->data == NULL) && unlikely(lazy_init(b))) return 1; if(unlikely(buffer_reserve(b, b->len + n))) return 1; memcpy(b->data + b->len, data, n); b->len += n; return 0; }
static int rdata_base64_to_string(buffer_type *output, rdata_atom_type rdata, rr_type* ATTR_UNUSED(rr)) { int length; size_t size = rdata_atom_size(rdata); if(size == 0) return 1; buffer_reserve(output, size * 2 + 1); length = __b64_ntop(rdata_atom_data(rdata), size, (char *) buffer_current(output), size * 2); if (length > 0) { buffer_skip(output, length); } return length != -1; }
static void hex_to_string(buffer_type *output, const uint8_t *data, size_t size) { static const char hexdigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; size_t i; buffer_reserve(output, size * 2); for (i = 0; i < size; ++i) { uint8_t octet = *data++; buffer_write_u8(output, hexdigits[octet >> 4]); buffer_write_u8(output, hexdigits[octet & 0x0f]); } }