Пример #1
0
static void
accepted_socket_invoke_user_cb(struct event_callback *dcb, void *arg)
{
	struct accepting_socket *as = arg;

	struct sockaddr *sa_local=NULL, *sa_remote=NULL;
	int socklen_local=0, socklen_remote=0;
	const struct win32_extension_fns *ext = event_get_win32_extension_fns_();
	struct evconnlistener *lev = &as->lev->base;
	evutil_socket_t sock=-1;
	void *data;
	evconnlistener_cb cb=NULL;
	evconnlistener_errorcb errorcb=NULL;
	int error;

	EVUTIL_ASSERT(ext->GetAcceptExSockaddrs);

	LOCK(lev);
	EnterCriticalSection(&as->lock);
	if (as->free_on_cb) {
		free_and_unlock_accepting_socket(as);
		listener_decref_and_unlock(lev);
		return;
	}

	++lev->refcnt;

	error = as->error;
	if (error) {
		as->error = 0;
		errorcb = lev->errorcb;
	} else {
		ext->GetAcceptExSockaddrs(
			as->addrbuf, 0, as->buflen/2, as->buflen/2,
			&sa_local, &socklen_local, &sa_remote,
			&socklen_remote);
		sock = as->s;
		cb = lev->cb;
		as->s = INVALID_SOCKET;

		/* We need to call this so getsockname, getpeername, and
		 * shutdown work correctly on the accepted socket. */
		/* XXXX handle error? */
		setsockopt(sock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
		    (char *)&as->lev->fd, sizeof(&as->lev->fd));
	}
	data = lev->user_data;

	LeaveCriticalSection(&as->lock);
	UNLOCK(lev);

	if (errorcb) {
		WSASetLastError(error);
		errorcb(lev, data);
	} else if (cb) {
		cb(lev, sock, sa_remote, socklen_remote, data);
	}

	LOCK(lev);
	if (listener_decref_and_unlock(lev))
		return;

	EnterCriticalSection(&as->lock);
	start_accepting(as);
	LeaveCriticalSection(&as->lock);
}
// These stubs are used by the compiler only.
// Argument registers, which must be preserved:
//   rcx - receiver (always first argument)
//   rdx - second argument (if any)
// Other registers that might be usable:
//   rax - inline cache register (is interface for itable stub)
//   rbx - method (used when calling out to interpreter)
// Available now, but may become callee-save at some point:
//   rsi, rdi
// Note that rax and rdx are also used for return values.
//
VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
  const int i486_code_length = VtableStub::pd_code_size_limit(true);
  VtableStub* s = new(i486_code_length) VtableStub(true, vtable_index);
  ResourceMark rm;
  CodeBuffer cb(s->entry_point(), i486_code_length);
  MacroAssembler* masm = new MacroAssembler(&cb);

#ifndef PRODUCT

  if (CountCompiledCalls) {
    __ incrementl(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
  }
#endif /* PRODUCT */

  // get receiver (need to skip return address on top of stack)
  assert(VtableStub::receiver_location() == rcx->as_VMReg(), "receiver expected in rcx");

  // get receiver klass
  address npe_addr = __ pc();
  __ movptr(rax, Address(rcx, oopDesc::klass_offset_in_bytes()));

#ifndef PRODUCT
  if (DebugVtables) {
    Label L;
    // check offset vs vtable length
    __ cmpl(Address(rax, instanceKlass::vtable_length_offset()*wordSize), vtable_index*vtableEntry::size());
    __ jcc(Assembler::greater, L);
    __ movl(rbx, vtable_index);
    __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), rcx, rbx);
    __ bind(L);
  }
#endif // PRODUCT

  const Register method = rbx;

  // load methodOop and target address
  __ lookup_virtual_method(rax, vtable_index, method);

  if (DebugVtables) {
    Label L;
    __ cmpptr(method, (int32_t)NULL_WORD);
    __ jcc(Assembler::equal, L);
    __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD);
    __ jcc(Assembler::notZero, L);
    __ stop("Vtable entry is NULL");
    __ bind(L);
  }

  // rax,: receiver klass
  // method (rbx): methodOop
  // rcx: receiver
  address ame_addr = __ pc();
  __ jmp( Address(method, methodOopDesc::from_compiled_offset()));

  masm->flush();

  if (PrintMiscellaneous && (WizardMode || Verbose)) {
    tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d",
                  vtable_index, s->entry_point(),
                  (int)(s->code_end() - s->entry_point()),
                  (int)(s->code_end() - __ pc()));
  }
  guarantee(__ pc() <= s->code_end(), "overflowed buffer");
  // shut the door on sizing bugs
  int slop = 3;  // 32-bit offset is this much larger than an 8-bit one
  assert(vtable_index > 10 || __ pc() + slop <= s->code_end(), "room for 32-bit offset");

  s->set_exception_points(npe_addr, ame_addr);
  return s;
}
Пример #3
0
static int conn_state(BIO *bio, BIO_CONNECT *c) {
  int ret = -1, i;
  int (*cb)(const BIO *, int, int) = NULL;

  if (c->info_callback != NULL) {
    cb = c->info_callback;
  }

  for (;;) {
    switch (c->state) {
      case BIO_CONN_S_BEFORE:
        /* If there's a hostname and a port, assume that both are
         * exactly what they say. If there is only a hostname, try
         * (just once) to split it into a hostname and port. */

        if (c->param_hostname == NULL) {
          OPENSSL_PUT_ERROR(BIO, BIO_R_NO_HOSTNAME_SPECIFIED);
          goto exit_loop;
        }

        if (c->param_port == NULL) {
          char *host, *port;
          if (!split_host_and_port(&host, &port, c->param_hostname) ||
              port == NULL) {
            OPENSSL_free(host);
            OPENSSL_free(port);
            OPENSSL_PUT_ERROR(BIO, BIO_R_NO_PORT_SPECIFIED);
            ERR_add_error_data(2, "host=", c->param_hostname);
            goto exit_loop;
          }

          OPENSSL_free(c->param_port);
          c->param_port = port;
          OPENSSL_free(c->param_hostname);
          c->param_hostname = host;
        }

        if (!bio_ip_and_port_to_socket_and_addr(
                &bio->num, &c->them, &c->them_length, c->param_hostname,
                c->param_port)) {
          OPENSSL_PUT_ERROR(BIO, BIO_R_UNABLE_TO_CREATE_SOCKET);
          ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
          goto exit_loop;
        }

        if (c->nbio) {
          if (!bio_socket_nbio(bio->num, 1)) {
            OPENSSL_PUT_ERROR(BIO, BIO_R_ERROR_SETTING_NBIO);
            ERR_add_error_data(4, "host=", c->param_hostname, ":",
                               c->param_port);
            goto exit_loop;
          }
        }

        i = 1;
        ret = setsockopt(bio->num, SOL_SOCKET, SO_KEEPALIVE, (char *)&i,
                         sizeof(i));
        if (ret < 0) {
          OPENSSL_PUT_SYSTEM_ERROR();
          OPENSSL_PUT_ERROR(BIO, BIO_R_KEEPALIVE);
          ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
          goto exit_loop;
        }

        BIO_clear_retry_flags(bio);
        ret = connect(bio->num, (struct sockaddr*) &c->them, c->them_length);
        if (ret < 0) {
          if (bio_fd_should_retry(ret)) {
            BIO_set_flags(bio, (BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY));
            c->state = BIO_CONN_S_BLOCKED_CONNECT;
            bio->retry_reason = BIO_RR_CONNECT;
          } else {
            OPENSSL_PUT_SYSTEM_ERROR();
            OPENSSL_PUT_ERROR(BIO, BIO_R_CONNECT_ERROR);
            ERR_add_error_data(4, "host=", c->param_hostname, ":",
                               c->param_port);
          }
          goto exit_loop;
        } else {
          c->state = BIO_CONN_S_OK;
        }
        break;

      case BIO_CONN_S_BLOCKED_CONNECT:
        i = bio_sock_error(bio->num);
        if (i) {
          if (bio_fd_should_retry(ret)) {
            BIO_set_flags(bio, (BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY));
            c->state = BIO_CONN_S_BLOCKED_CONNECT;
            bio->retry_reason = BIO_RR_CONNECT;
            ret = -1;
          } else {
            BIO_clear_retry_flags(bio);
            OPENSSL_PUT_SYSTEM_ERROR();
            OPENSSL_PUT_ERROR(BIO, BIO_R_NBIO_CONNECT_ERROR);
            ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
            ret = 0;
          }
          goto exit_loop;
        } else {
          c->state = BIO_CONN_S_OK;
        }
        break;

      case BIO_CONN_S_OK:
        ret = 1;
        goto exit_loop;
      default:
        assert(0);
        goto exit_loop;
    }

    if (cb != NULL) {
      ret = cb((BIO *)bio, c->state, ret);
      if (ret == 0) {
        goto end;
      }
    }
  }

exit_loop:
  if (cb != NULL) {
    ret = cb((BIO *)bio, c->state, ret);
  }

end:
  return ret;
}
Пример #4
0
call_in_callback_cb_t NetworkStack::get_call_in_callback()
{
    call_in_callback_cb_t cb(this, &NetworkStack::call_in);
    return cb;
}
VtableStub* VtableStubs::create_itable_stub(int itable_index) {
  // Note well: pd_code_size_limit is the absolute minimum we can get away with.  If you
  //            add code here, bump the code stub size returned by pd_code_size_limit!
  const int i486_code_length = VtableStub::pd_code_size_limit(false);
  VtableStub* s = new(i486_code_length) VtableStub(false, itable_index);
  ResourceMark rm;
  CodeBuffer cb(s->entry_point(), i486_code_length);
  MacroAssembler* masm = new MacroAssembler(&cb);

  // Entry arguments:
  //  rax,: Interface
  //  rcx: Receiver

#ifndef PRODUCT
  if (CountCompiledCalls) {
    __ incrementl(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
  }
#endif /* PRODUCT */
  // get receiver (need to skip return address on top of stack)

  assert(VtableStub::receiver_location() == rcx->as_VMReg(), "receiver expected in rcx");

  // get receiver klass (also an implicit null-check)
  address npe_addr = __ pc();
  __ movptr(rsi, Address(rcx, oopDesc::klass_offset_in_bytes()));

  // Most registers are in use; we'll use rax, rbx, rsi, rdi
  // (If we need to make rsi, rdi callee-save, do a push/pop here.)
  const Register method = rbx;
  Label throw_icce;

  // Get methodOop and entrypoint for compiler
  __ lookup_interface_method(// inputs: rec. class, interface, itable index
                             rsi, rax, itable_index,
                             // outputs: method, scan temp. reg
                             method, rdi,
                             throw_icce);

  // method (rbx): methodOop
  // rcx: receiver

#ifdef ASSERT
  if (DebugVtables) {
      Label L1;
      __ cmpptr(method, (int32_t)NULL_WORD);
      __ jcc(Assembler::equal, L1);
      __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD);
      __ jcc(Assembler::notZero, L1);
      __ stop("methodOop is null");
      __ bind(L1);
    }
#endif // ASSERT

  address ame_addr = __ pc();
  __ jmp(Address(method, methodOopDesc::from_compiled_offset()));

  __ bind(throw_icce);
  __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry()));
  masm->flush();

  if (PrintMiscellaneous && (WizardMode || Verbose)) {
    tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d",
                  itable_index, s->entry_point(),
                  (int)(s->code_end() - s->entry_point()),
                  (int)(s->code_end() - __ pc()));
  }
  guarantee(__ pc() <= s->code_end(), "overflowed buffer");
  // shut the door on sizing bugs
  int slop = 3;  // 32-bit offset is this much larger than an 8-bit one
  assert(itable_index > 10 || __ pc() + slop <= s->code_end(), "room for 32-bit offset");

  s->set_exception_points(npe_addr, ame_addr);
  return s;
}
Пример #6
0
/*-
 * Return up to 'len' payload bytes received in 'type' records.
 * 'type' is one of the following:
 *
 *   -  SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
 *   -  SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
 *   -  0 (during a shutdown, no data has to be returned)
 *
 * If we don't have stored data to work from, read a SSL/TLS record first
 * (possibly multiple records if we still don't have anything to return).
 *
 * This function must handle any surprises the peer may have for us, such as
 * Alert records (e.g. close_notify) or renegotiation requests. ChangeCipherSpec
 * messages are treated as if they were handshake messages *if* the |recd_type|
 * argument is non NULL.
 * Also if record payloads contain fragments too small to process, we store
 * them until there is enough for the respective protocol (the record protocol
 * may use arbitrary fragmentation and even interleaving):
 *     Change cipher spec protocol
 *             just 1 byte needed, no need for keeping anything stored
 *     Alert protocol
 *             2 bytes needed (AlertLevel, AlertDescription)
 *     Handshake protocol
 *             4 bytes needed (HandshakeType, uint24 length) -- we just have
 *             to detect unexpected Client Hello and Hello Request messages
 *             here, anything else is handled by higher layers
 *     Application data protocol
 *             none of our business
 */
int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
                     int len, int peek)
{
    int al, i, j, ret;
    unsigned int n;
    SSL3_RECORD *rr;
    void (*cb) (const SSL *ssl, int type2, int val) = NULL;

    if (!SSL3_BUFFER_is_initialised(&s->rlayer.rbuf)) {
        /* Not initialized yet */
        if (!ssl3_setup_buffers(s))
            return (-1);
    }

    if ((type && (type != SSL3_RT_APPLICATION_DATA) &&
         (type != SSL3_RT_HANDSHAKE)) ||
        (peek && (type != SSL3_RT_APPLICATION_DATA))) {
        SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
        return -1;
    }

    /*
     * check whether there's a handshake message (client hello?) waiting
     */
    if ((ret = have_handshake_fragment(s, type, buf, len)))
        return ret;

    /*
     * Now s->rlayer.d->handshake_fragment_len == 0 if
     * type == SSL3_RT_HANDSHAKE.
     */

#ifndef OPENSSL_NO_SCTP
    /*
     * Continue handshake if it had to be interrupted to read app data with
     * SCTP.
     */
    if ((!ossl_statem_get_in_handshake(s) && SSL_in_init(s)) ||
        (BIO_dgram_is_sctp(SSL_get_rbio(s))
         && ossl_statem_in_sctp_read_sock(s)
         && s->s3->in_read_app_data != 2))
#else
    if (!ossl_statem_get_in_handshake(s) && SSL_in_init(s))
#endif
    {
        /* type == SSL3_RT_APPLICATION_DATA */
        i = s->handshake_func(s);
        if (i < 0)
            return (i);
        if (i == 0) {
            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
            return (-1);
        }
    }

 start:
    s->rwstate = SSL_NOTHING;

    /*-
     * s->s3->rrec.type         - is the type of record
     * s->s3->rrec.data,    - data
     * s->s3->rrec.off,     - offset into 'data' for next read
     * s->s3->rrec.length,  - number of bytes.
     */
    rr = s->rlayer.rrec;

    /*
     * We are not handshaking and have no data yet, so process data buffered
     * during the last handshake in advance, if any.
     */
    if (SSL_is_init_finished(s) && SSL3_RECORD_get_length(rr) == 0) {
        pitem *item;
        item = pqueue_pop(s->rlayer.d->buffered_app_data.q);
        if (item) {
#ifndef OPENSSL_NO_SCTP
            /* Restore bio_dgram_sctp_rcvinfo struct */
            if (BIO_dgram_is_sctp(SSL_get_rbio(s))) {
                DTLS1_RECORD_DATA *rdata = (DTLS1_RECORD_DATA *)item->data;
                BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_SET_RCVINFO,
                         sizeof(rdata->recordinfo), &rdata->recordinfo);
            }
#endif

            dtls1_copy_record(s, item);

            OPENSSL_free(item->data);
            pitem_free(item);
        }
    }

    /* Check for timeout */
    if (dtls1_handle_timeout(s) > 0)
        goto start;

    /* get new packet if necessary */
    if ((SSL3_RECORD_get_length(rr) == 0)
        || (s->rlayer.rstate == SSL_ST_READ_BODY)) {
        ret = dtls1_get_record(s);
        if (ret <= 0) {
            ret = dtls1_read_failed(s, ret);
            /* anything other than a timeout is an error */
            if (ret <= 0)
                return (ret);
            else
                goto start;
        }
    }

    /*
     * Reset the count of consecutive warning alerts if we've got a non-empty
     * record that isn't an alert.
     */
    if (SSL3_RECORD_get_type(rr) != SSL3_RT_ALERT
            && SSL3_RECORD_get_length(rr) != 0)
        s->rlayer.alert_count = 0;

    /* we now have a packet which can be read and processed */

    if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
                                   * reset by ssl3_get_finished */
        && (SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE)) {
        /*
         * We now have application data between CCS and Finished. Most likely
         * the packets were reordered on their way, so buffer the application
         * data for later processing rather than dropping the connection.
         */
        if (dtls1_buffer_record(s, &(s->rlayer.d->buffered_app_data),
                                SSL3_RECORD_get_seq_num(rr)) < 0) {
            SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
            return -1;
        }
        SSL3_RECORD_set_length(rr, 0);
        goto start;
    }

    /*
     * If the other end has shut down, throw anything we read away (even in
     * 'peek' mode)
     */
    if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
        SSL3_RECORD_set_length(rr, 0);
        s->rwstate = SSL_NOTHING;
        return (0);
    }

    if (type == SSL3_RECORD_get_type(rr)
        || (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC
            && type == SSL3_RT_HANDSHAKE && recvd_type != NULL)) {
        /*
         * SSL3_RT_APPLICATION_DATA or
         * SSL3_RT_HANDSHAKE or
         * SSL3_RT_CHANGE_CIPHER_SPEC
         */
        /*
         * make sure that we are not getting application data when we are
         * doing a handshake for the first time
         */
        if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
            (s->enc_read_ctx == NULL)) {
            al = SSL_AD_UNEXPECTED_MESSAGE;
            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_APP_DATA_IN_HANDSHAKE);
            goto f_err;
        }

        if (recvd_type != NULL)
            *recvd_type = SSL3_RECORD_get_type(rr);

        if (len <= 0)
            return (len);

        if ((unsigned int)len > SSL3_RECORD_get_length(rr))
            n = SSL3_RECORD_get_length(rr);
        else
            n = (unsigned int)len;

        memcpy(buf, &(SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)]), n);
        if (!peek) {
            SSL3_RECORD_sub_length(rr, n);
            SSL3_RECORD_add_off(rr, n);
            if (SSL3_RECORD_get_length(rr) == 0) {
                s->rlayer.rstate = SSL_ST_READ_HEADER;
                SSL3_RECORD_set_off(rr, 0);
            }
        }
#ifndef OPENSSL_NO_SCTP
        /*
         * We were about to renegotiate but had to read belated application
         * data first, so retry.
         */
        if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
            SSL3_RECORD_get_type(rr) == SSL3_RT_APPLICATION_DATA &&
            ossl_statem_in_sctp_read_sock(s)) {
            s->rwstate = SSL_READING;
            BIO_clear_retry_flags(SSL_get_rbio(s));
            BIO_set_retry_read(SSL_get_rbio(s));
        }

        /*
         * We might had to delay a close_notify alert because of reordered
         * app data. If there was an alert and there is no message to read
         * anymore, finally set shutdown.
         */
        if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
            s->d1->shutdown_received
            && !BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) {
            s->shutdown |= SSL_RECEIVED_SHUTDOWN;
            return (0);
        }
#endif
        return (n);
    }

    /*
     * If we get here, then type != rr->type; if we have a handshake message,
     * then it was unexpected (Hello Request or Client Hello).
     */

    /*
     * In case of record types for which we have 'fragment' storage, fill
     * that so that we can process the data at a fixed place.
     */
    {
        unsigned int k, dest_maxlen = 0;
        unsigned char *dest = NULL;
        unsigned int *dest_len = NULL;

        if (SSL3_RECORD_get_type(rr) == SSL3_RT_HANDSHAKE) {
            dest_maxlen = sizeof s->rlayer.d->handshake_fragment;
            dest = s->rlayer.d->handshake_fragment;
            dest_len = &s->rlayer.d->handshake_fragment_len;
        } else if (SSL3_RECORD_get_type(rr) == SSL3_RT_ALERT) {
            dest_maxlen = sizeof(s->rlayer.d->alert_fragment);
            dest = s->rlayer.d->alert_fragment;
            dest_len = &s->rlayer.d->alert_fragment_len;
        }
#ifndef OPENSSL_NO_HEARTBEATS
        else if (SSL3_RECORD_get_type(rr) == DTLS1_RT_HEARTBEAT) {
            /* We allow a 0 return */
            if (dtls1_process_heartbeat(s, SSL3_RECORD_get_data(rr),
                                        SSL3_RECORD_get_length(rr)) < 0) {
                return -1;
            }
            /* Exit and notify application to read again */
            SSL3_RECORD_set_length(rr, 0);
            s->rwstate = SSL_READING;
            BIO_clear_retry_flags(SSL_get_rbio(s));
            BIO_set_retry_read(SSL_get_rbio(s));
            return (-1);
        }
#endif
        /* else it's a CCS message, or application data or wrong */
        else if (SSL3_RECORD_get_type(rr) != SSL3_RT_CHANGE_CIPHER_SPEC) {
            /*
             * Application data while renegotiating is allowed. Try again
             * reading.
             */
            if (SSL3_RECORD_get_type(rr) == SSL3_RT_APPLICATION_DATA) {
                BIO *bio;
                s->s3->in_read_app_data = 2;
                bio = SSL_get_rbio(s);
                s->rwstate = SSL_READING;
                BIO_clear_retry_flags(bio);
                BIO_set_retry_read(bio);
                return (-1);
            }

            /* Not certain if this is the right error handling */
            al = SSL_AD_UNEXPECTED_MESSAGE;
            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
            goto f_err;
        }

        if (dest_maxlen > 0) {
            /*
             * XDTLS: In a pathological case, the Client Hello may be
             * fragmented--don't always expect dest_maxlen bytes
             */
            if (SSL3_RECORD_get_length(rr) < dest_maxlen) {
#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
                /*
                 * for normal alerts rr->length is 2, while
                 * dest_maxlen is 7 if we were to handle this
                 * non-existing alert...
                 */
                FIX ME;
#endif
                s->rlayer.rstate = SSL_ST_READ_HEADER;
                SSL3_RECORD_set_length(rr, 0);
                goto start;
            }

            /* now move 'n' bytes: */
            for (k = 0; k < dest_maxlen; k++) {
                dest[k] = SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)];
                SSL3_RECORD_add_off(rr, 1);
                SSL3_RECORD_add_length(rr, -1);
            }
            *dest_len = dest_maxlen;
        }
    }

    /*-
     * s->rlayer.d->handshake_fragment_len == 12  iff  rr->type == SSL3_RT_HANDSHAKE;
     * s->rlayer.d->alert_fragment_len == 7      iff  rr->type == SSL3_RT_ALERT.
     * (Possibly rr is 'empty' now, i.e. rr->length may be 0.)
     */

    /* If we are a client, check for an incoming 'Hello Request': */
    if ((!s->server) &&
        (s->rlayer.d->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) &&
        (s->rlayer.d->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
        (s->session != NULL) && (s->session->cipher != NULL)) {
        s->rlayer.d->handshake_fragment_len = 0;

        if ((s->rlayer.d->handshake_fragment[1] != 0) ||
            (s->rlayer.d->handshake_fragment[2] != 0) ||
            (s->rlayer.d->handshake_fragment[3] != 0)) {
            al = SSL_AD_DECODE_ERROR;
            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_HELLO_REQUEST);
            goto f_err;
        }

        /*
         * no need to check sequence number on HELLO REQUEST messages
         */

        if (s->msg_callback)
            s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
                            s->rlayer.d->handshake_fragment, 4, s,
                            s->msg_callback_arg);

        if (SSL_is_init_finished(s) &&
            !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
            !s->s3->renegotiate) {
            s->d1->handshake_read_seq++;
            s->new_session = 1;
            ssl3_renegotiate(s);
            if (ssl3_renegotiate_check(s)) {
                i = s->handshake_func(s);
                if (i < 0)
                    return (i);
                if (i == 0) {
                    SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
                    return (-1);
                }

                if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
                    if (SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0) {
                        /* no read-ahead left? */
                        BIO *bio;
                        /*
                         * In the case where we try to read application data,
                         * but we trigger an SSL handshake, we return -1 with
                         * the retry option set.  Otherwise renegotiation may
                         * cause nasty problems in the blocking world
                         */
                        s->rwstate = SSL_READING;
                        bio = SSL_get_rbio(s);
                        BIO_clear_retry_flags(bio);
                        BIO_set_retry_read(bio);
                        return (-1);
                    }
                }
            }
        }
        /*
         * we either finished a handshake or ignored the request, now try
         * again to obtain the (application) data we were asked for
         */
        goto start;
    }

    if (s->rlayer.d->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH) {
        int alert_level = s->rlayer.d->alert_fragment[0];
        int alert_descr = s->rlayer.d->alert_fragment[1];

        s->rlayer.d->alert_fragment_len = 0;

        if (s->msg_callback)
            s->msg_callback(0, s->version, SSL3_RT_ALERT,
                            s->rlayer.d->alert_fragment, 2, s,
                            s->msg_callback_arg);

        if (s->info_callback != NULL)
            cb = s->info_callback;
        else if (s->ctx->info_callback != NULL)
            cb = s->ctx->info_callback;

        if (cb != NULL) {
            j = (alert_level << 8) | alert_descr;
            cb(s, SSL_CB_READ_ALERT, j);
        }

        if (alert_level == SSL3_AL_WARNING) {
            s->s3->warn_alert = alert_descr;

            s->rlayer.alert_count++;
            if (s->rlayer.alert_count == MAX_WARN_ALERT_COUNT) {
                al = SSL_AD_UNEXPECTED_MESSAGE;
                SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS);
                goto f_err;
            }

            if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
#ifndef OPENSSL_NO_SCTP
                /*
                 * With SCTP and streams the socket may deliver app data
                 * after a close_notify alert. We have to check this first so
                 * that nothing gets discarded.
                 */
                if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
                    BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) {
                    s->d1->shutdown_received = 1;
                    s->rwstate = SSL_READING;
                    BIO_clear_retry_flags(SSL_get_rbio(s));
                    BIO_set_retry_read(SSL_get_rbio(s));
                    return -1;
                }
#endif
                s->shutdown |= SSL_RECEIVED_SHUTDOWN;
                return (0);
            }
#if 0
            /* XXX: this is a possible improvement in the future */
            /* now check if it's a missing record */
            if (alert_descr == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) {
                unsigned short seq;
                unsigned int frag_off;
                unsigned char *p = &(s->rlayer.d->alert_fragment[2]);

                n2s(p, seq);
                n2l3(p, frag_off);

                dtls1_retransmit_message(s,
                                         dtls1_get_queue_priority
                                         (frag->msg_header.seq, 0), frag_off,
                                         &found);
                if (!found && SSL_in_init(s)) {
                    /*
                     * fprintf( stderr,"in init = %d\n", SSL_in_init(s));
                     */
                    /*
                     * requested a message not yet sent, send an alert
                     * ourselves
                     */
                    ssl3_send_alert(s, SSL3_AL_WARNING,
                                    DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
                }
            }
#endif
        } else if (alert_level == SSL3_AL_FATAL) {
            char tmp[16];

            s->rwstate = SSL_NOTHING;
            s->s3->fatal_alert = alert_descr;
            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);
            BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr);
            ERR_add_error_data(2, "SSL alert number ", tmp);
            s->shutdown |= SSL_RECEIVED_SHUTDOWN;
            SSL_CTX_remove_session(s->session_ctx, s->session);
            return (0);
        } else {
            al = SSL_AD_ILLEGAL_PARAMETER;
            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNKNOWN_ALERT_TYPE);
            goto f_err;
        }

        goto start;
    }

    if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a
                                            * shutdown */
        s->rwstate = SSL_NOTHING;
        SSL3_RECORD_set_length(rr, 0);
        return (0);
    }

    if (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC) {
        /*
         * We can't process a CCS now, because previous handshake messages
         * are still missing, so just drop it.
         */
        SSL3_RECORD_set_length(rr, 0);
        goto start;
    }

    /*
     * Unexpected handshake message (Client Hello, or protocol violation)
     */
    if ((s->rlayer.d->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) &&
        !ossl_statem_get_in_handshake(s)) {
        struct hm_header_st msg_hdr;

        /* this may just be a stale retransmit */
        dtls1_get_message_header(rr->data, &msg_hdr);
        if (SSL3_RECORD_get_epoch(rr) != s->rlayer.d->r_epoch) {
            SSL3_RECORD_set_length(rr, 0);
            goto start;
        }

        /*
         * If we are server, we may have a repeated FINISHED of the client
         * here, then retransmit our CCS and FINISHED.
         */
        if (msg_hdr.type == SSL3_MT_FINISHED) {
            if (dtls1_check_timeout_num(s) < 0)
                return -1;

            dtls1_retransmit_buffered_messages(s);
            SSL3_RECORD_set_length(rr, 0);
            goto start;
        }

        if (SSL_is_init_finished(s) &&
            !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) {
            ossl_statem_set_in_init(s, 1);
            s->renegotiate = 1;
            s->new_session = 1;
        }
        i = s->handshake_func(s);
        if (i < 0)
            return (i);
        if (i == 0) {
            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
            return (-1);
        }

        if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
            if (SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0) {
                /* no read-ahead left? */
                BIO *bio;
                /*
                 * In the case where we try to read application data, but we
                 * trigger an SSL handshake, we return -1 with the retry
                 * option set.  Otherwise renegotiation may cause nasty
                 * problems in the blocking world
                 */
                s->rwstate = SSL_READING;
                bio = SSL_get_rbio(s);
                BIO_clear_retry_flags(bio);
                BIO_set_retry_read(bio);
                return (-1);
            }
        }
        goto start;
    }

    switch (SSL3_RECORD_get_type(rr)) {
    default:
        /* TLS just ignores unknown message types */
        if (s->version == TLS1_VERSION) {
            SSL3_RECORD_set_length(rr, 0);
            goto start;
        }
        al = SSL_AD_UNEXPECTED_MESSAGE;
        SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
        goto f_err;
    case SSL3_RT_CHANGE_CIPHER_SPEC:
    case SSL3_RT_ALERT:
    case SSL3_RT_HANDSHAKE:
        /*
         * we already handled all of these, with the possible exception of
         * SSL3_RT_HANDSHAKE when ossl_statem_get_in_handshake(s) is true, but
         * that should not happen when type != rr->type
         */
        al = SSL_AD_UNEXPECTED_MESSAGE;
        SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
        goto f_err;
    case SSL3_RT_APPLICATION_DATA:
        /*
         * At this point, we were expecting handshake data, but have
         * application data.  If the library was running inside ssl3_read()
         * (i.e. in_read_app_data is set) and it makes sense to read
         * application data at this point (session renegotiation not yet
         * started), we will indulge it.
         */
        if (s->s3->in_read_app_data &&
            (s->s3->total_renegotiations != 0) &&
            ossl_statem_app_data_allowed(s)) {
            s->s3->in_read_app_data = 2;
            return (-1);
        } else {
            al = SSL_AD_UNEXPECTED_MESSAGE;
            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
            goto f_err;
        }
    }
    /* not reached */

 f_err:
    ssl3_send_alert(s, SSL3_AL_FATAL, al);
    return (-1);
}
Пример #7
0
 nmethod*           nm()         const {
     assert( cb() != NULL && cb()->is_nmethod(), "usage");
     return (nmethod*) cb();
 }
void func_call (char *x, char* y, void (*cb) (char *))
{
  cb (y);
  *x = (*y)++;
}
Пример #9
0
/* returns 0 on success, or <0 on read failure                 */
int decaps_hdlc(int fd, int (*cb)(int cl, void *pack, unsigned int len), int cl)
{
    unsigned char buffer[PACKET_MAX];
    unsigned int start = 0;
    int end;
    int status;
    static unsigned int len = 0, escape = 0;
    static unsigned char copy[PACKET_MAX];
    static int checkedsync = 0;
    /* start is start of packet.  end is end of buffer data */
    /*  this is the only blocking read we will allow */
    if ((end = read (fd, buffer, sizeof(buffer))) <= 0) {
        int saved_errno = errno;
        warn("short read (%d): %s", end, strerror(saved_errno));
        switch (saved_errno) {
        case EMSGSIZE: {
            socklen_t optval, optlen = sizeof(optval);
            warn("transmitted GRE packet triggered an ICMP destination unreachable, fragmentation needed, or exceeds the MTU of the network interface");
#define IP_MTU 14
            if(getsockopt(fd, IPPROTO_IP, IP_MTU, &optval, &optlen) < 0)
                warn("getsockopt: %s", strerror(errno));
            warn("getsockopt: IP_MTU: %d\n", optval);
            return 0;
        }
        case EIO:
            warn("pppd may have shutdown, see pppd log");
            break;
        }
        return -1;
    }
    /* warn if the sync options of ppp and pptp don't match */
    if( !checkedsync) {
        checkedsync = 1;
        if( buffer[0] == HDLC_FLAG) {
            if( syncppp )
                warn( "pptp --sync option is active, "
                      "yet the ppp mode is asynchronous!\n");
        }
        else if( !syncppp )
            warn( "The ppp mode is synchronous, "
                  "yet no pptp --sync option is specified!\n");
    }
    /* in synchronous mode there are no hdlc control characters nor checksum
     * bytes. Find end of packet with the length information in the PPP packet
     */
    if ( syncppp ) {
        while ( start + 8 < end) {
            len = ntoh16(*(short int *)(buffer + start + 6)) + 4;
            /* note: the buffer may contain an incomplete packet at the end
             * this packet will be read again at the next read() */
            if ( start + len <= end)
                if ((status = cb (cl, buffer + start, len)) < 0)
                    return status; /* error-check */
            start += len;
        }
        return 0;
    }
    /* asynchronous mode */
    while (start < end) {
        /* Copy to 'copy' and un-escape as we go. */
        while (buffer[start] != HDLC_FLAG) {
            if ((escape == 0) && buffer[start] == HDLC_ESCAPE) {
                escape = HDLC_TRANSPARENCY;
            } else {
                if (len < PACKET_MAX)
                    copy [len++] = buffer[start] ^ escape;
                escape = 0;
            }
            start++;
            if (start >= end)
                return 0; /* No more data, but the frame is not complete yet. */
        }
        /* found flag.  skip past it */
        start++;
        /* check for over-short packets and silently discard, as per RFC1662 */
        if ((len < 4) || (escape != 0)) {
            len = 0;
            escape = 0;
            continue;
        }
        /* check, then remove the 16-bit FCS checksum field */
        if (pppfcs16 (PPPINITFCS16, copy, len) != PPPGOODFCS16)
            warn("Bad Frame Check Sequence during PPP to GRE decapsulation");
        len -= sizeof(u_int16_t);
        /* so now we have a packet of length 'len' in 'copy' */
        if ((status = cb (cl, copy, len)) < 0)
            return status; /* error-check */
        /* Great!  Let's do more! */
        len = 0;
        escape = 0;
    }
    return 0;
    /* No more data to process. */
}
Пример #10
0
static void ril_file_info_cb(struct ril_msg *message, gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_sim_file_info_cb_t cb = cbd->cb;
	struct sim_data *sd = cbd->user;
	struct ofono_error error;
	gboolean ok = FALSE;
	int sw1 = 0, sw2 = 0, response_len = 0;
	int flen = 0, rlen = 0, str = 0;
	guchar *response = NULL;
	guchar access[3] = { 0x00, 0x00, 0x00 };
	guchar file_status = EF_STATUS_VALID;

	DBG("");

	/* In case sim card has been removed prior to this callback has been
	 * called we must not call the core call back method as otherwise the
	 * core will crash.
	 */
	if (sd->removed == TRUE) {
		ofono_error("RIL_CARDSTATE_ABSENT");
		return;
	}

	if (message->error == RIL_E_SUCCESS) {
		decode_ril_error(&error, "OK");
	} else {
		DBG("Reply failure: %s", ril_error_to_string(message->error));
		decode_ril_error(&error, "FAIL");
		goto error;
	}

	if ((response = (guchar *)
		ril_util_parse_sim_io_rsp(sd->ril,
						message,
						&sw1,
						&sw2,
						&response_len)) == NULL) {
		ofono_error("Can't parse SIM IO response from RILD");
		decode_ril_error(&error, "FAIL");
		goto error;
	}

	if ((sw1 != 0x90 && sw1 != 0x91 && sw1 != 0x92 && sw1 != 0x9f) ||
		(sw1 == 0x90 && sw2 != 0x00)) {
		ofono_error("invalid values: sw1: %02x sw2: %02x", sw1, sw2);
		memset(&error, 0, sizeof(error));

		/* TODO: fix decode_ril_error to take type & error */

		error.type = OFONO_ERROR_TYPE_SIM;
		error.error = (sw1 << 8) | sw2;

		goto error;
	}

	if (response_len) {
		if (response[0] == 0x62) {
			ok = sim_parse_3g_get_response(
				response, response_len,
				&flen, &rlen, &str, access, NULL);
		} else
			ok = sim_parse_2g_get_response(
				response, response_len,
				&flen, &rlen, &str, access, &file_status);
	}

	if (!ok) {
		ofono_error("parse response failed");
		decode_ril_error(&error, "FAIL");
		goto error;
	}

	cb(&error, flen, str, rlen, access, file_status, cbd->data);
	g_free(response);
	return;

error:
	cb(&error, -1, -1, -1, NULL, EF_STATUS_INVALIDATED, cbd->data);
	g_free(response);
}
Пример #11
0
void CompactingPermGenGen::generate_vtable_methods(void** vtbl_list,
                                                   void** vtable,
                                                   char** md_top,
                                                   char* md_end,
                                                   char** mc_top,
                                                   char* mc_end) {

  intptr_t vtable_bytes = (num_virtuals * vtbl_list_size) * sizeof(void*);
  *(intptr_t *)(*md_top) = vtable_bytes;
  *md_top += sizeof(intptr_t);
  void** dummy_vtable = (void**)*md_top;
  *vtable = dummy_vtable;
  *md_top += vtable_bytes;

  // Get ready to generate dummy methods.

  CodeBuffer cb((unsigned char*)*mc_top, mc_end - *mc_top);
  MacroAssembler* masm = new MacroAssembler(&cb);

  Label common_code;
  for (int i = 0; i < vtbl_list_size; ++i) {
    for (int j = 0; j < num_virtuals; ++j) {
      dummy_vtable[num_virtuals * i + j] = (void*)masm->pc();

      // Load eax with a value indicating vtable/offset pair.
      // -- bits[ 7..0]  (8 bits) which virtual method in table?
      // -- bits[12..8]  (5 bits) which virtual method table?
      // -- must fit in 13-bit instruction immediate field.
      __ movl(rax, (i << 8) + j);
      __ jmp(common_code);
    }
  }

  __ bind(common_code);

  // Expecting to be called with "thiscall" convections -- the arguments
  // are on the stack and the "this" pointer is in c_rarg0. In addition, rax
  // was set (above) to the offset of the method in the table.

  __ push(c_rarg1);                     // save & free register
  __ push(c_rarg0);                     // save "this"
  __ mov(c_rarg0, rax);
  __ shrptr(c_rarg0, 8);                // isolate vtable identifier.
  __ shlptr(c_rarg0, LogBytesPerWord);
  __ lea(c_rarg1, ExternalAddress((address)vtbl_list)); // ptr to correct vtable list.
  __ addptr(c_rarg1, c_rarg0);          // ptr to list entry.
  __ movptr(c_rarg1, Address(c_rarg1, 0));      // get correct vtable address.
  __ pop(c_rarg0);                      // restore "this"
  __ movptr(Address(c_rarg0, 0), c_rarg1);      // update vtable pointer.

  __ andptr(rax, 0x00ff);                       // isolate vtable method index
  __ shlptr(rax, LogBytesPerWord);
  __ addptr(rax, c_rarg1);              // address of real method pointer.
  __ pop(c_rarg1);                      // restore register.
  __ movptr(rax, Address(rax, 0));      // get real method pointer.
  __ jmp(rax);                          // jump to the real method.

  __ flush();

  *mc_top = (char*)__ pc();
}
Пример #12
0
static void at_crsm_info_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
	struct cb_data *cbd = user_data;
	GAtResultIter iter;
	ofono_sim_file_info_cb_t cb = cbd->cb;
	struct ofono_error error;
	const guint8 *response;
	gint sw1, sw2, len;
	int flen, rlen;
	int str;
	unsigned char access[3];
	unsigned char file_status;

	decode_at_error(&error, g_at_result_final_response(result));

	if (!ok) {
		cb(&error, -1, -1, -1, NULL, EF_STATUS_INVALIDATED, cbd->data);
		return;
	}

	g_at_result_iter_init(&iter, result);

	if (!g_at_result_iter_next(&iter, "+CRSM:"))
		goto error;

	g_at_result_iter_next_number(&iter, &sw1);
	g_at_result_iter_next_number(&iter, &sw2);

	if (!g_at_result_iter_next_hexstring(&iter, &response, &len) ||
			(sw1 != 0x90 && sw1 != 0x91 && sw1 != 0x92) ||
			(sw1 == 0x90 && sw2 != 0x00)) {
		memset(&error, 0, sizeof(error));

		error.type = OFONO_ERROR_TYPE_SIM;
		error.error = (sw1 << 8) | sw2;

		cb(&error, -1, -1, -1, NULL, EF_STATUS_INVALIDATED, cbd->data);
		return;
	}

	DBG("crsm_info_cb: %02x, %02x, %i", sw1, sw2, len);

	if (response[0] == 0x62) {
		ok = sim_parse_3g_get_response(response, len, &flen, &rlen,
						&str, access, NULL);

		file_status = EF_STATUS_VALID;
	} else
		ok = sim_parse_2g_get_response(response, len, &flen, &rlen,
						&str, access, &file_status);

	if (!ok)
		goto error;

	cb(&error, flen, str, rlen, access, file_status, cbd->data);

	return;

error:
	CALLBACK_WITH_FAILURE(cb, -1, -1, -1, NULL,
				EF_STATUS_INVALIDATED, cbd->data);
}
Пример #13
0
static void
mainloop(void)
{
  gtimer_t *gti;
  gti_callback_t *cb;
  struct timespec ts;

  while(tvheadend_running) {
    clock_gettime(CLOCK_REALTIME, &ts);

    /* 1sec stuff */
    if (ts.tv_sec > dispatch_clock) {
      dispatch_clock = ts.tv_sec;

      spawn_reaper(); /* reap spawned processes */

      comet_flush(); /* Flush idle comet mailboxes */
    }

    /* Global timers */
    pthread_mutex_lock(&global_lock);

    // TODO: there is a risk that if timers re-insert themselves to
    //       the top of the list with a 0 offset we could loop indefinitely
    
#if 0
    tvhdebug("gtimer", "now %ld.%09ld", ts.tv_sec, ts.tv_nsec);
    LIST_FOREACH(gti, &gtimers, gti_link)
      tvhdebug("gtimer", "  gti %p expire %ld.%08ld",
               gti, gti->gti_expire.tv_sec, gti->gti_expire.tv_nsec);
#endif

    while((gti = LIST_FIRST(&gtimers)) != NULL) {
      
      if ((gti->gti_expire.tv_sec > ts.tv_sec) ||
          ((gti->gti_expire.tv_sec == ts.tv_sec) &&
           (gti->gti_expire.tv_nsec > ts.tv_nsec))) {
        ts = gti->gti_expire;
        break;
      }

      cb = gti->gti_callback;
      //tvhdebug("gtimer", "%p callback", gti);

      LIST_REMOVE(gti, gti_link);
      gti->gti_callback = NULL;

      cb(gti->gti_opaque);
    }

    /* Bound wait */
    if ((LIST_FIRST(&gtimers) == NULL) || (ts.tv_sec > (dispatch_clock + 1))) {
      ts.tv_sec  = dispatch_clock + 1;
      ts.tv_nsec = 0;
    }

    /* Wait */
    //tvhdebug("gtimer", "wait till %ld.%09ld", ts.tv_sec, ts.tv_nsec);
    pthread_cond_timedwait(&gtimer_cond, &global_lock, &ts);
    pthread_mutex_unlock(&global_lock);
  }
}
Пример #14
0
static void
ubus_process_invoke(struct ubus_context *ctx, struct ubus_msghdr *hdr,
		    struct ubus_object *obj, struct blob_attr **attrbuf)
{
	struct ubus_request_data req = {
		.fd = -1,
	};
	int method;
	int ret;
	bool no_reply = false;

	if (!obj) {
		ret = UBUS_STATUS_NOT_FOUND;
		goto send;
	}

	if (!attrbuf[UBUS_ATTR_METHOD]) {
		ret = UBUS_STATUS_INVALID_ARGUMENT;
		goto send;
	}

	if (attrbuf[UBUS_ATTR_NO_REPLY])
		no_reply = blob_get_int8(attrbuf[UBUS_ATTR_NO_REPLY]);

	req.peer = hdr->peer;
	req.seq = hdr->seq;
	req.object = obj->id;

	for (method = 0; method < obj->n_methods; method++)
		if (!obj->methods[method].name ||
		    !strcmp(obj->methods[method].name,
		            blob_data(attrbuf[UBUS_ATTR_METHOD])))
			goto found;

	/* not found */
	ret = UBUS_STATUS_METHOD_NOT_FOUND;
	goto send;

found:
	ret = obj->methods[method].handler(ctx, obj, &req,
					   blob_data(attrbuf[UBUS_ATTR_METHOD]),
					   attrbuf[UBUS_ATTR_DATA]);
	if (req.deferred || no_reply)
		return;

send:
	ubus_complete_deferred_request(ctx, &req, ret);
}

void __hidden ubus_process_obj_msg(struct ubus_context *ctx, struct ubus_msghdr_buf *buf)
{
	void (*cb)(struct ubus_context *, struct ubus_msghdr *,
		   struct ubus_object *, struct blob_attr **);
	struct ubus_msghdr *hdr = &buf->hdr;
	struct blob_attr **attrbuf;
	struct ubus_object *obj;
	uint32_t objid;
	void *prev_data = NULL;

	attrbuf = ubus_parse_msg(buf->data);
	if (!attrbuf[UBUS_ATTR_OBJID])
		return;

	objid = blob_get_u32(attrbuf[UBUS_ATTR_OBJID]);
	obj = avl_find_element(&ctx->objects, &objid, obj, avl);

	switch (hdr->type) {
	case UBUS_MSG_INVOKE:
		cb = ubus_process_invoke;
		break;
	case UBUS_MSG_UNSUBSCRIBE:
		cb = ubus_process_unsubscribe;
		break;
	case UBUS_MSG_NOTIFY:
		cb = ubus_process_notify;
		break;
	default:
		return;
	}

	if (buf == &ctx->msgbuf) {
		prev_data = buf->data;
		buf->data = NULL;
	}

	cb(ctx, hdr, obj, attrbuf);

	if (prev_data) {
		if (buf->data)
			free(prev_data);
		else
			buf->data = prev_data;
	}
}
Пример #15
0
int ssl23_connect(SSL *s)
	{
	BUF_MEM *buf=NULL;
	unsigned long Time=(unsigned long)time(NULL);
	void (*cb)(const SSL *ssl,int type,int val)=NULL;
	int ret= -1;
	int new_state,state;

	RAND_add(&Time,sizeof(Time),0);
	ERR_clear_error();
	clear_sys_error();

	if (s->info_callback != NULL)
		cb=s->info_callback;
	else if (s->ctx->info_callback != NULL)
		cb=s->ctx->info_callback;
	
	s->in_handshake++;
	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); 

	for (;;)
		{
		state=s->state;

		switch(s->state)
			{
		case SSL_ST_BEFORE:
		case SSL_ST_CONNECT:
		case SSL_ST_BEFORE|SSL_ST_CONNECT:
		case SSL_ST_OK|SSL_ST_CONNECT:

			if (s->session != NULL)
				{
				SSLerr(SSL_F_SSL23_CONNECT,SSL_R_SSL23_DOING_SESSION_ID_REUSE);
				ret= -1;
				goto end;
				}
			s->server=0;
			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);

			/* s->version=TLS1_VERSION; */
			s->type=SSL_ST_CONNECT;

			if (s->init_buf == NULL)
				{
				if ((buf=BUF_MEM_new()) == NULL)
					{
					ret= -1;
					goto end;
					}
				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
					{
					ret= -1;
					goto end;
					}
				s->init_buf=buf;
				buf=NULL;
				}

			if (!ssl3_setup_buffers(s)) { ret= -1; goto end; }

			ssl3_init_finished_mac(s);

			s->state=SSL23_ST_CW_CLNT_HELLO_A;
			s->ctx->stats.sess_connect++;
			s->init_num=0;
			break;

		case SSL23_ST_CW_CLNT_HELLO_A:
		case SSL23_ST_CW_CLNT_HELLO_B:

			s->shutdown=0;
			ret=ssl23_client_hello(s);
			if (ret <= 0) goto end;
			s->state=SSL23_ST_CR_SRVR_HELLO_A;
			s->init_num=0;

			break;

		case SSL23_ST_CR_SRVR_HELLO_A:
		case SSL23_ST_CR_SRVR_HELLO_B:
			ret=ssl23_get_server_hello(s);
			if (ret >= 0) cb=NULL;
			goto end;
			/* break; */

		default:
			SSLerr(SSL_F_SSL23_CONNECT,SSL_R_UNKNOWN_STATE);
			ret= -1;
			goto end;
			/* break; */
			}

		if (s->debug) { (void)BIO_flush(s->wbio); }

		if ((cb != NULL) && (s->state != state))
			{
			new_state=s->state;
			s->state=state;
			cb(s,SSL_CB_CONNECT_LOOP,1);
			s->state=new_state;
			}
		}
end:
	s->in_handshake--;
	if (buf != NULL)
		BUF_MEM_free(buf);
	if (cb != NULL)
		cb(s,SSL_CB_CONNECT_EXIT,ret);
	return(ret);
	}
Пример #16
0
static void pincode_reply(DBusPendingCall *call, void *user_data)
{
	struct agent_request *req = user_data;
	struct agent *agent = req->agent;
	struct btd_adapter *adapter = agent->adapter;
	agent_pincode_cb cb = req->cb;
	DBusMessage *message;
	DBusError err;
	bdaddr_t sba;
	size_t len;
	char *pin;

	adapter_get_address(adapter, &sba);

	/* steal_reply will always return non-NULL since the callback
	 * is only called after a reply has been received */
	message = dbus_pending_call_steal_reply(call);

	dbus_error_init(&err);
	if (dbus_set_error_from_message(&err, message)) {
		if ((g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err.name) ||
				g_str_equal(DBUS_ERROR_NO_REPLY, err.name)) &&
				request_fallback(req, pincode_reply) == 0) {
			dbus_error_free(&err);
			return;
		}

		error("Agent replied with an error: %s, %s",
				err.name, err.message);

		cb(agent, &err, NULL, req->user_data);
		dbus_error_free(&err);
		goto done;
	}

	dbus_error_init(&err);
	if (!dbus_message_get_args(message, &err,
				DBUS_TYPE_STRING, &pin,
				DBUS_TYPE_INVALID)) {
		error("Wrong passkey reply signature: %s", err.message);
		cb(agent, &err, NULL, req->user_data);
		dbus_error_free(&err);
		goto done;
	}

	len = strlen(pin);

	dbus_error_init(&err);
	if (len > 16 || len < 1) {
		error("Invalid passkey length from handler");
		dbus_set_error_const(&err, "org.bluez.Error.InvalidArgs",
					"Invalid passkey length");
		cb(agent, &err, NULL, req->user_data);
		dbus_error_free(&err);
		goto done;
	}

	set_pin_length(&sba, len);

	cb(agent, NULL, pin, req->user_data);

done:
	if (message)
		dbus_message_unref(message);

	dbus_pending_call_cancel(req->call);
	agent->request = NULL;
	agent_request_free(req, TRUE);
}
Пример #17
0
void *
rust_dbg_call(dbg_callback cb, void *data) {
    return cb(data);
}
Пример #18
0
/*
 * INTEGER specific human-readable output.
 */
static ssize_t
INTEGER__dump(asn_TYPE_descriptor_t *td, const INTEGER_t *st, asn_app_consume_bytes_f *cb, void *app_key, int plainOrXER) {
	asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
	char scratch[32];	/* Enough for 64-bit integer */
	uint8_t *buf = st->buf;
	uint8_t *buf_end = st->buf + st->size;
	signed long value;
	ssize_t wrote = 0;
	char *p;
	int ret;

	if(specs && specs->field_unsigned)
		ret = asn_INTEGER2ulong(st, (unsigned long *)&value);
	else
		ret = asn_INTEGER2long(st, &value);

	/* Simple case: the integer size is small */
	if(ret == 0) {
		const asn_INTEGER_enum_map_t *el;
		size_t scrsize;
		char *scr;

		el = (value >= 0 || !specs || !specs->field_unsigned)
			? INTEGER_map_value2enum(specs, value) : 0;
		if(el) {
			scrsize = el->enum_len + 32;
			scr = (char *)alloca(scrsize);
			if(plainOrXER == 0)
				ret = snprintf(scr, scrsize,
					"%ld (%s)", value, el->enum_name);
			else
				ret = snprintf(scr, scrsize,
					"<%s/>", el->enum_name);
		} else if(plainOrXER && specs && specs->strict_enumeration) {
			ASN_DEBUG("ASN.1 forbids dealing with "
				"unknown value of ENUMERATED type");
			errno = EPERM;
			return -1;
		} else {
			scrsize = sizeof(scratch);
			scr = scratch;
			ret = snprintf(scr, scrsize,
				(specs && specs->field_unsigned)
				?"%lu":"%ld", value);
		}
		assert(ret > 0 && (size_t)ret < scrsize);
		return (cb(scr, ret, app_key) < 0) ? -1 : ret;
	} else if(plainOrXER && specs && specs->strict_enumeration) {
		/*
		 * Here and earlier, we cannot encode the ENUMERATED values
		 * if there is no corresponding identifier.
		 */
		ASN_DEBUG("ASN.1 forbids dealing with "
			"unknown value of ENUMERATED type");
		errno = EPERM;
		return -1;
	}

	/* Output in the long xx:yy:zz... format */
	/* TODO: replace with generic algorithm (Knuth TAOCP Vol 2, 4.3.1) */
	for(p = scratch; buf < buf_end; buf++) {
		static const char *h2c = "0123456789ABCDEF";
		if((p - scratch) >= (ssize_t)(sizeof(scratch) - 4)) {
			/* Flush buffer */
			if(cb(scratch, p - scratch, app_key) < 0)
				return -1;
			wrote += p - scratch;
			p = scratch;
		}
		*p++ = h2c[*buf >> 4];
		*p++ = h2c[*buf & 0x0F];
		*p++ = 0x3a;	/* ":" */
	}
	if(p != scratch)
		p--;	/* Remove the last ":" */

	wrote += p - scratch;
	return (cb(scratch, p - scratch, app_key) < 0) ? -1 : wrote;
}
Пример #19
0
HTTPResult
HTTP_get(struct HTTP_ctx *http, const char *url, HTTP_read_callback *cb)
{
  char *host, *path;
  char *p1, *p2;
  char hbuf[256];
  int port = 80;
#ifdef CRYPTO
  int ssl = 0;
#endif
  int hlen;
  long flen = 0;
  int rc, i;
  int len_known;
  HTTPResult ret = HTTPRES_OK;
  struct sockaddr_in sa;
  RTMPSockBuf sb = {0};

  http->status = -1;

  memset(&sa, 0, sizeof(struct sockaddr_in));
  sa.sin_family = AF_INET;

  /* we only handle http here */
  if (strncasecmp(url, "http", 4))
    return HTTPRES_BAD_REQUEST;

  if (url[4] == 's')
    {
#ifdef CRYPTO
      ssl = 1;
      port = 443;
      if (!RTMP_TLS_ctx)
	RTMP_TLS_Init();
#else
      return HTTPRES_BAD_REQUEST;
#endif
    }

  p1 = strchr(url + 4, ':');
  if (!p1 || strncmp(p1, "://", 3))
    return HTTPRES_BAD_REQUEST;

  host = p1 + 3;
  path = strchr(host, '/');
  hlen = path - host;
  strncpy(hbuf, host, hlen);
  hbuf[hlen] = '\0';
  host = hbuf;
  p1 = strrchr(host, ':');
  if (p1)
    {
      *p1++ = '\0';
      port = atoi(p1);
    }

  sa.sin_addr.s_addr = inet_addr(host);
  if (sa.sin_addr.s_addr == INADDR_NONE)
    {
      struct hostent *hp = gethostbyname(host);
      if (!hp || !hp->h_addr)
	return HTTPRES_LOST_CONNECTION;
      sa.sin_addr = *(struct in_addr *)hp->h_addr;
    }
  sa.sin_port = htons(port);
  sb.sb_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (sb.sb_socket == -1)
    return HTTPRES_LOST_CONNECTION;
  i =
    sprintf(sb.sb_buf,
	    "GET %s HTTP/1.0\r\nUser-Agent: %s\r\nHost: %s\r\nReferer: %.*s\r\n",
	    path, AGENT, host, (int)(path - url + 1), url);
  if (http->date[0])
    i += sprintf(sb.sb_buf + i, "If-Modified-Since: %s\r\n", http->date);
  i += sprintf(sb.sb_buf + i, "\r\n");

  if (connect
      (sb.sb_socket, (struct sockaddr *)&sa, sizeof(struct sockaddr)) < 0)
    {
      ret = HTTPRES_LOST_CONNECTION;
      goto leave;
    }
#ifdef CRYPTO
  if (ssl)
    {
#ifdef NO_SSL
      RTMP_Log(RTMP_LOGERROR, "%s, No SSL/TLS support", __FUNCTION__);
      ret = HTTPRES_BAD_REQUEST;
      goto leave;
#else
      TLS_client(RTMP_TLS_ctx, sb.sb_ssl);
      TLS_setfd(sb.sb_ssl, sb.sb_socket);
      if (TLS_connect(sb.sb_ssl) < 0)
	{
	  RTMP_Log(RTMP_LOGERROR, "%s, TLS_Connect failed", __FUNCTION__);
	  ret = HTTPRES_LOST_CONNECTION;
	  goto leave;
	}
#endif
    }
#endif
  RTMPSockBuf_Send(&sb, sb.sb_buf, i);

  /* set timeout */
#define HTTP_TIMEOUT	5
  {
    SET_RCVTIMEO(tv, HTTP_TIMEOUT);
    if (setsockopt
        (sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)))
      {
        RTMP_Log(RTMP_LOGERROR, "%s, Setting socket timeout to %ds failed!",
	    __FUNCTION__, HTTP_TIMEOUT);
      }
  }

  sb.sb_size = 0;
  sb.sb_timedout = FALSE;
  if (RTMPSockBuf_Fill(&sb) < 1)
    {
      ret = HTTPRES_LOST_CONNECTION;
      goto leave;
    }
  if (strncmp(sb.sb_buf, "HTTP/1", 6))
    {
      ret = HTTPRES_BAD_REQUEST;
      goto leave;
    }

  p1 = strchr(sb.sb_buf, ' ');
  rc = atoi(p1 + 1);
  http->status = rc;

  if (rc >= 300)
    {
      if (rc == 304)
	{
	  ret = HTTPRES_OK_NOT_MODIFIED;
	  goto leave;
	}
      else if (rc == 404)
	ret = HTTPRES_NOT_FOUND;
      else if (rc >= 500)
	ret = HTTPRES_SERVER_ERROR;
      else if (rc >= 400)
	ret = HTTPRES_BAD_REQUEST;
      else
	ret = HTTPRES_REDIRECTED;
    }

  p1 = memchr(sb.sb_buf, '\n', sb.sb_size);
  if (!p1)
    {
      ret = HTTPRES_BAD_REQUEST;
      goto leave;
    }
  sb.sb_start = p1 + 1;
  sb.sb_size -= sb.sb_start - sb.sb_buf;

  while ((p2 = memchr(sb.sb_start, '\r', sb.sb_size)))
    {
      if (*sb.sb_start == '\r')
	{
	  sb.sb_start += 2;
	  sb.sb_size -= 2;
	  break;
	}
      else
	if (!strncasecmp
	    (sb.sb_start, "Content-Length: ", sizeof("Content-Length: ") - 1))
	{
	  flen = strtol(sb.sb_start + sizeof("Content-Length: ") - 1, NULL, 10);
	  if (flen < 1 || flen > INT_MAX)
	  {
	    ret = HTTPRES_BAD_REQUEST;
	    goto leave;
	  }
	}
      else
	if (!strncasecmp
	    (sb.sb_start, "Last-Modified: ", sizeof("Last-Modified: ") - 1))
	{
	  *p2 = '\0';
	  strncpy(http->date, sb.sb_start + sizeof("Last-Modified: ") - 1, DATELEN-1);
	  http->date[DATELEN-1] = '\0';
	}
      p2 += 2;
      sb.sb_size -= p2 - sb.sb_start;
      sb.sb_start = p2;
      if (sb.sb_size < 1)
	{
	  if (RTMPSockBuf_Fill(&sb) < 1)
	    {
	      ret = HTTPRES_LOST_CONNECTION;
	      goto leave;
	    }
	}
    }

  len_known = flen > 0;
  while ((!len_known || flen > 0) &&
	 (sb.sb_size > 0 || RTMPSockBuf_Fill(&sb) > 0))
    {
      cb(sb.sb_start, 1, sb.sb_size, http->data);
      if (len_known)
	flen -= sb.sb_size;
      http->size += sb.sb_size;
      sb.sb_size = 0;
    }

  if (flen > 0)
    ret = HTTPRES_LOST_CONNECTION;

leave:
  RTMPSockBuf_Close(&sb);
  return ret;
}
Пример #20
0
static int conn_state(BIO *b, BIO_CONNECT *c)
	{
	int ret= -1,i;
	unsigned long l;
	char *p,*q;
	int (*cb)()=NULL;

	if (c->info_callback != NULL)
		cb=c->info_callback;

	for (;;)
		{
		switch (c->state)
			{
		case BIO_CONN_S_BEFORE:
			p=c->param_hostname;
			if (p == NULL)
				{
				BIOerr(BIO_F_CONN_STATE,BIO_R_NO_HOSTNAME_SPECIFIED);
				goto exit_loop;
				}
			for ( ; *p != '\0'; p++)
				{
				if ((*p == ':') || (*p == '/')) break;
				}

			i= *p;
			if ((i == ':') || (i == '/'))
				{

				*(p++)='\0';
				if (i == ':')
					{
					for (q=p; *q; q++)
						if (*q == '/')
							{
							*q='\0';
							break;
							}
					if (c->param_port != NULL)
						OPENSSL_free(c->param_port);
					c->param_port=BUF_strdup(p);
					}
				}

			if (c->param_port == NULL)
				{
				BIOerr(BIO_F_CONN_STATE,BIO_R_NO_PORT_SPECIFIED);
				ERR_add_error_data(2,"host=",c->param_hostname);
				goto exit_loop;
				}
			c->state=BIO_CONN_S_GET_IP;
			break;

		case BIO_CONN_S_GET_IP:
			if (BIO_get_host_ip(c->param_hostname,&(c->ip[0])) <= 0)
				goto exit_loop;
			c->state=BIO_CONN_S_GET_PORT;
			break;

		case BIO_CONN_S_GET_PORT:
			if (c->param_port == NULL)
				{
				/* abort(); */
				goto exit_loop;
				}
			else if (BIO_get_port(c->param_port,&c->port) <= 0)
				goto exit_loop;
			c->state=BIO_CONN_S_CREATE_SOCKET;
			break;

		case BIO_CONN_S_CREATE_SOCKET:
			/* now setup address */
			memset((char *)&c->them,0,sizeof(c->them));
			c->them.sin_family=AF_INET;
			c->them.sin_port=htons((unsigned short)c->port);
			l=(unsigned long)
				((unsigned long)c->ip[0]<<24L)|
				((unsigned long)c->ip[1]<<16L)|
				((unsigned long)c->ip[2]<< 8L)|
				((unsigned long)c->ip[3]);
			c->them.sin_addr.s_addr=htonl(l);
			c->state=BIO_CONN_S_CREATE_SOCKET;

			ret=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
			if (ret == INVALID_SOCKET)
				{
				SYSerr(SYS_F_SOCKET,get_last_socket_error());
				ERR_add_error_data(4,"host=",c->param_hostname,
					":",c->param_port);
				BIOerr(BIO_F_CONN_STATE,BIO_R_UNABLE_TO_CREATE_SOCKET);
				goto exit_loop;
				}
			b->num=ret;
			c->state=BIO_CONN_S_NBIO;
			break;

		case BIO_CONN_S_NBIO:
			if (c->nbio)
				{
				if (!BIO_socket_nbio(b->num,1))
					{
					BIOerr(BIO_F_CONN_STATE,BIO_R_ERROR_SETTING_NBIO);
					ERR_add_error_data(4,"host=",
						c->param_hostname,
						":",c->param_port);
					goto exit_loop;
					}
				}
			c->state=BIO_CONN_S_CONNECT;

#if defined(SO_KEEPALIVE) && !defined(MPE)
			i=1;
			i=setsockopt(b->num,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
			if (i < 0)
				{
				SYSerr(SYS_F_SOCKET,get_last_socket_error());
				ERR_add_error_data(4,"host=",c->param_hostname,
					":",c->param_port);
				BIOerr(BIO_F_CONN_STATE,BIO_R_KEEPALIVE);
				goto exit_loop;
				}
#endif
			break;

		case BIO_CONN_S_CONNECT:
			BIO_clear_retry_flags(b);
			ret=connect(b->num,
				(struct sockaddr *)&c->them,
				sizeof(c->them));
			b->retry_reason=0;
			if (ret < 0)
				{
				if (BIO_sock_should_retry(ret))
					{
					BIO_set_retry_special(b);
					c->state=BIO_CONN_S_BLOCKED_CONNECT;
					b->retry_reason=BIO_RR_CONNECT;
					}
				else
					{
					SYSerr(SYS_F_CONNECT,get_last_socket_error());
					ERR_add_error_data(4,"host=",
						c->param_hostname,
						":",c->param_port);
					BIOerr(BIO_F_CONN_STATE,BIO_R_CONNECT_ERROR);
					}
				goto exit_loop;
				}
			else
				c->state=BIO_CONN_S_OK;
			break;

		case BIO_CONN_S_BLOCKED_CONNECT:
			i=BIO_sock_error(b->num);
			if (i)
				{
				BIO_clear_retry_flags(b);
				SYSerr(SYS_F_CONNECT,i);
				ERR_add_error_data(4,"host=",
					c->param_hostname,
					":",c->param_port);
				BIOerr(BIO_F_CONN_STATE,BIO_R_NBIO_CONNECT_ERROR);
				ret=0;
				goto exit_loop;
				}
			else
				c->state=BIO_CONN_S_OK;
			break;

		case BIO_CONN_S_OK:
			ret=1;
			goto exit_loop;
		default:
			/* abort(); */
			goto exit_loop;
			}

		if (cb != NULL)
			{
			if (!(ret=cb((BIO *)b,c->state,ret)))
				goto end;
			}
		}

	/* Loop does not exit */
exit_loop:
	if (cb != NULL)
		ret=cb((BIO *)b,c->state,ret);
end:
	return(ret);
	}
Пример #21
0
inline bool vframeStreamCommon::fill_from_frame() {
  // Interpreted frame
  if (_frame.is_interpreted_frame()) {
    fill_from_interpreter_frame();
    return true;
  }

  // Compiled frame

  if (cb() != NULL && cb()->is_nmethod()) {
    if (nm()->is_native_method()) {
      // Do not rely on scopeDesc since the pc might be unprecise due to the _last_native_pc trick.
      fill_from_compiled_native_frame();
    } else {
      PcDesc* pc_desc = nm()->pc_desc_at(_frame.pc());
      int decode_offset;
      if (pc_desc == NULL) {
        // Should not happen, but let fill_from_compiled_frame handle it.

        // If we are trying to walk the stack of a thread that is not
        // at a safepoint (like AsyncGetCallTrace would do) then this is an
        // acceptable result. [ This is assuming that safe_for_sender
        // is so bullet proof that we can trust the frames it produced. ]
        //
        // So if we see that the thread is not safepoint safe
        // then simply produce the method and a bci of zero
        // and skip the possibility of decoding any inlining that
        // may be present. That is far better than simply stopping (or
        // asserting. If however the thread is safepoint safe this
        // is the sign of a compiler bug  and we'll let
        // fill_from_compiled_frame handle it.


        JavaThreadState state = _thread->thread_state();

        // in_Java should be good enough to test safepoint safety
        // if state were say in_Java_trans then we'd expect that
        // the pc would have already been slightly adjusted to
        // one that would produce a pcDesc since the trans state
        // would be one that might in fact anticipate a safepoint

        if (state == _thread_in_Java ) {
          // This will get a method a zero bci and no inlining.
          // Might be nice to have a unique bci to signify this
          // particular case but for now zero will do.

          fill_from_compiled_native_frame();

          // There is something to be said for setting the mode to
          // at_end_mode to prevent trying to walk further up the
          // stack. There is evidence that if we walk any further
          // that we could produce a bad stack chain. However until
          // we see evidence that allowing this causes us to find
          // frames bad enough to cause segv's or assertion failures
          // we don't do it as while we may get a bad call chain the
          // probability is much higher (several magnitudes) that we
          // get good data.

          return true;
        }
        decode_offset = DebugInformationRecorder::serialized_null;
      } else {
        decode_offset = pc_desc->scope_decode_offset();
      }
      fill_from_compiled_frame(decode_offset);
    }
    return true;
  }

  // End of stack?
  if (_frame.is_first_frame() || (_stop_at_java_call_stub && _frame.is_entry_frame())) {
    _mode = at_end_mode;
    return true;
  }

  return false;
}
Пример #22
0
static void ext_device_restore_read_device_formats_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
    pa_operation *o = userdata;
    int eol = 1;

    pa_assert(pd);
    pa_assert(o);
    pa_assert(PA_REFCNT_VALUE(o) >= 1);

    if (!o->context)
        goto finish;

    if (command != PA_COMMAND_REPLY) {
        if (pa_context_handle_error(o->context, command, t, false) < 0)
            goto finish;

        eol = -1;
    } else {
        uint8_t j;

        while (!pa_tagstruct_eof(t)) {
            pa_ext_device_restore_info i;
            pa_zero(i);

            if (pa_tagstruct_getu32(t, &i.type) < 0 ||
                    pa_tagstruct_getu32(t, &i.index) < 0 ||
                    pa_tagstruct_getu8(t, &i.n_formats) < 0) {

                pa_context_fail(o->context, PA_ERR_PROTOCOL);
                goto finish;
            }

            if (PA_DEVICE_TYPE_SINK != i.type && PA_DEVICE_TYPE_SOURCE != i.type) {
                pa_context_fail(o->context, PA_ERR_PROTOCOL);
                goto finish;
            }

            if (i.index == PA_INVALID_INDEX) {
                pa_context_fail(o->context, PA_ERR_PROTOCOL);
                goto finish;
            }

            if (i.n_formats > 0) {
                i.formats = pa_xnew0(pa_format_info*, i.n_formats);

                for (j = 0; j < i.n_formats; j++) {

                    pa_format_info *f = i.formats[j] = pa_format_info_new();
                    if (pa_tagstruct_get_format_info(t, f) < 0) {
                        uint8_t k;

                        pa_context_fail(o->context, PA_ERR_PROTOCOL);
                        for (k = 0; k < j+1; k++)
                            pa_format_info_free(i.formats[k]);
                        pa_xfree(i.formats);
                        goto finish;
                    }
                }
            }

            if (o->callback) {
                pa_ext_device_restore_read_device_formats_cb_t cb = (pa_ext_device_restore_read_device_formats_cb_t) o->callback;
                cb(o->context, &i, 0, o->userdata);
            }

            for (j = 0; j < i.n_formats; j++)
                pa_format_info_free(i.formats[j]);
            pa_xfree(i.formats);
        }
    }