コード例 #1
0
/*** vector_insert*************************************************************
 * nice thing about file descriptors is that we are assured by POSIX
 * that they are monotonically increasing.
 */
int vector_insert(VECTOR *v, int key, PPTP_CALL * call)
{
    int i;
    assert(v != NULL && call != NULL);
    assert(!vector_contains(v, key));
#ifdef VECTOR_DEBUG
    assert(v->key_max < key);
#endif
    if (!(v->size < v->alloc)) {
        void *tmp = realloc(v->item, sizeof(*(v->item)) * 2 * v->alloc);
        if (tmp != NULL) {
            v->alloc *= 2;
            v->item = tmp;
        } else return FALSE; /* failed to alloc memory. */
    }
    assert(v->size < v->alloc);
    /* for safety, we make this work in the general case;
     * but this is optimized for adding call to the end of the vector.
     */
    for(i = v->size - 1; i >= 0; i--)
        if (v->item[i].key < key)
            break;
    /* insert after item i */
    memmove(&v->item[i + 2], &v->item[i + 1],
            (v->size - i - 1) * sizeof(*(v->item)));
    v->item[i + 1].key  = key;
    v->item[i + 1].call = call;
    v->size++;
#ifdef VECTOR_DEBUG
    if (v->key_max < key) /* ie, always. */
        v->key_max = key;
#endif
    return TRUE;
}
コード例 #2
0
ファイル: pptp_ctrl.c プロジェクト: a170785/buildroot
/*** hard close ***************************************************************/
void pptp_call_destroy(PPTP_CONN *conn, PPTP_CALL *call)
{
    assert(conn && conn->call); assert(call);
    assert(vector_contains(conn->call, call->call_id));
    /* notify */
    if (call->callback != NULL) call->callback(conn, call, CALL_CLOSE_DONE);
    /* deallocate */
    vector_remove(conn->call, call->call_id);
    free(call);
}
コード例 #3
0
ファイル: pptp_callmgr.c プロジェクト: OPSF/uClinux
/* Call callback */
void call_callback(PPTP_CONN *conn, PPTP_CALL *call, enum call_state state) {
  struct local_callinfo *lci;
  struct local_conninfo *conninfo;
  u_int16_t call_id[2];

  switch(state) {
  case CALL_OPEN_DONE:
    /* okey dokey.  This means that the call_id and peer_call_id are now
     * valid, so lets send them on to our friends who requested this call.
     */
	pptp_debug("About to get the call closure stuff");
    lci = pptp_call_closure_get(conn, call); assert(lci != NULL);
    pptp_call_get_ids(conn, call, &call_id[0], &call_id[1]);
	pptp_debug("writing out the call_ids");
	if (lci)
    write(lci->unix_sock, (char *) &call_id, sizeof(call_id));
    /* Our duty to the fatherland is now complete. */
    break;
  case CALL_OPEN_FAIL:
  case CALL_CLOSE_RQST:
  case CALL_CLOSE_DONE:
    /* don't need to do anything here, except make sure tables are sync'ed */
    conninfo = pptp_conn_closure_get(conn);
    lci = pptp_call_closure_get(conn, call); 
    // assert(lci != NULL && conninfo != NULL);
    if (lci && conninfo &&
		vector_contains(conninfo->call_list, lci->unix_sock)) {
      vector_remove(conninfo->call_list, lci->unix_sock);
	  if (lci->unix_sock >= 0)
        FD_CLR(lci->unix_sock, conninfo->call_set);
//	  syslog(LOG_NOTICE, "Closing connection");
      kill(lci->pid[0], SIGTERM);
    }
	if (lci) {
	  pptp_debug("close %d", lci->unix_sock);
      close(lci->unix_sock);
	  lci->unix_sock = -1;
#if 0
	  memset(lci, 0, sizeof(*lci));
	  free(lci);
	  pptp_call_closure_put(conn, call, NULL); 
#endif
	}
    break;
  default:
    logmsg("Unhandled call callback state [%d].", (int) state);
    break;
  }
}
コード例 #4
0
ファイル: pptp_ctrl.c プロジェクト: a170785/buildroot
/*** pptp_call_close **********************************************************/
void pptp_call_close(PPTP_CONN * conn, PPTP_CALL * call)
{
    struct pptp_call_clear_rqst rqst = {
        PPTP_HEADER_CTRL(PPTP_CALL_CLEAR_RQST), 0, 0
    };
    assert(conn && conn->call); assert(call);
    assert(vector_contains(conn->call, call->call_id));
    /* haven't thought about PAC yet */
    assert(call->call_type == PPTP_CALL_PNS);
    assert(call->state.pns != PNS_IDLE);
    rqst.call_id = hton16(call->call_id);
    /* don't check state against WAIT_DISCONNECT... allow multiple disconnect
     * requests to be made.
     */
    pptp_send_ctrl_packet(conn, &rqst, sizeof(rqst));
    pptp_reset_timer();
    call->state.pns = PNS_WAIT_DISCONNECT;
    /* call structure will be freed when we have confirmation of disconnect. */
}
コード例 #5
0
/* Call callback */
void call_callback(PPTP_CONN *conn, PPTP_CALL *call, enum call_state state)
{
    struct local_callinfo *lci;
    struct local_conninfo *conninfo;
    u_int16_t call_id[2];
    switch(state) {
        case CALL_OPEN_DONE:
            /* okey dokey.  This means that the call_id and peer_call_id are
             * now valid, so lets send them on to our friends who requested
             * this call.  */
            lci = pptp_call_closure_get(conn, call); assert(lci != NULL);
            pptp_call_get_ids(conn, call, &call_id[0], &call_id[1]);
            write(lci->unix_sock, &call_id, sizeof(call_id));
            /* Our duty to the fatherland is now complete. */
            break;
        case CALL_OPEN_FAIL:
        case CALL_CLOSE_RQST:
        case CALL_CLOSE_DONE:
            /* don't need to do anything here, except make sure tables
             * are sync'ed */
            log("Closing connection (call state)");
            conninfo = pptp_conn_closure_get(conn);
            lci = pptp_call_closure_get(conn, call); 
            assert(lci != NULL && conninfo != NULL);
            if (vector_contains(conninfo->call_list, lci->unix_sock)) {
                vector_remove(conninfo->call_list, lci->unix_sock);
                close(lci->unix_sock);
                FD_CLR(lci->unix_sock, conninfo->call_set);
                if(lci->pid[0] > 1) kill(lci->pid[0], SIGTERM);
                if(lci->pid[1] > 1) kill(lci->pid[1], SIGTERM);
            }
            break;
        default:
            log("Unhandled call callback state [%d].", (int) state);
            break;
    }
}
コード例 #6
0
ファイル: pptp_ctrl.c プロジェクト: a170785/buildroot
/*** pptp_dispatch_ctrl_packet ************************************************/
int ctrlp_disp(PPTP_CONN * conn, void * buffer, size_t size)
{
    struct pptp_header *header = (struct pptp_header *)buffer;
    u_int8_t close_reason = PPTP_STOP_NONE;
    assert(conn && conn->call); assert(buffer);
    assert(ntoh32(header->magic) == PPTP_MAGIC);
    assert(ntoh16(header->length) == size);
    assert(ntoh16(header->pptp_type) == PPTP_MESSAGE_CONTROL);
    if (size < PPTP_CTRL_SIZE(ntoh16(header->ctrl_type))) {
        log("Invalid packet received [type: %d; length: %d].",
                (int) ntoh16(header->ctrl_type), (int) size);
        return 0;
    }
    switch (ntoh16(header->ctrl_type)) {
        /* ----------- STANDARD Start-Session MESSAGES ------------ */
        case PPTP_START_CTRL_CONN_RQST:
        {
            struct pptp_start_ctrl_conn *packet = 
                (struct pptp_start_ctrl_conn *) buffer;
            struct pptp_start_ctrl_conn reply = {
                PPTP_HEADER_CTRL(PPTP_START_CTRL_CONN_RPLY),
                hton16(PPTP_VERSION), 0, 0,
                hton32(PPTP_FRAME_CAP), hton32(PPTP_BEARER_CAP),
                hton16(PPTP_MAX_CHANNELS), hton16(PPTP_FIRMWARE_VERSION),
                PPTP_HOSTNAME, PPTP_VENDOR };
            int idx, rc;
            log("Received Start Control Connection Request");
            /* fix this packet, if necessary */
            idx = get_quirk_index();
            if (idx != -1 && pptp_fixups[idx].start_ctrl_conn) {
                if ((rc = pptp_fixups[idx].start_ctrl_conn(&reply)))
                    warn("calling the start_ctrl_conn hook failed (%d)", rc);
            }
            if (conn->conn_state == CONN_IDLE) {
                if (ntoh16(packet->version) < PPTP_VERSION) {
                    /* Can't support this (earlier) PPTP_VERSION */
                    reply.version = packet->version;
                    /* protocol version not supported */
                    reply.result_code = hton8(5);
                    pptp_send_ctrl_packet(conn, &reply, sizeof(reply));
                    pptp_reset_timer(); /* give sender a chance for a retry */
                } else { /* same or greater version */
                    if (pptp_send_ctrl_packet(conn, &reply, sizeof(reply))) {
                        conn->conn_state = CONN_ESTABLISHED;
                        log("server connection ESTABLISHED.");
                        pptp_reset_timer();
                    }
                }
            }
            break;
        }
        case PPTP_START_CTRL_CONN_RPLY:
        {
            struct pptp_start_ctrl_conn *packet = 
                (struct pptp_start_ctrl_conn *) buffer;
            log("Received Start Control Connection Reply");
            if (conn->conn_state == CONN_WAIT_CTL_REPLY) {
                /* XXX handle collision XXX [see rfc] */
                if (ntoh16(packet->version) != PPTP_VERSION) {
                    if (conn->callback != NULL)
                        conn->callback(conn, CONN_OPEN_FAIL);
                    close_reason = PPTP_STOP_PROTOCOL;
                    goto pptp_conn_close;
                }
                if (ntoh8(packet->result_code) != 1 &&
                    /* J'ai change le if () afin que la connection ne se ferme
                     * pas pour un "rien" :p [email protected] -
                     * 
                     * Don't close the connection if the result code is zero
                     * (feature found in certain ADSL modems)
                     */
                        ntoh8(packet->result_code) != 0) { 
                    log("Negative reply received to our Start Control "
                            "Connection Request");
                    ctrlp_error(packet->result_code, packet->error_code,
                            -1, pptp_start_ctrl_conn_rply,
                            MAX_START_CTRL_CONN_REPLY);
                    if (conn->callback != NULL)
                        conn->callback(conn, CONN_OPEN_FAIL);
                    close_reason = PPTP_STOP_PROTOCOL;
                    goto pptp_conn_close;
                }
                conn->conn_state = CONN_ESTABLISHED;
                /* log session properties */
                conn->version      = ntoh16(packet->version);
                conn->firmware_rev = ntoh16(packet->firmware_rev);
                memcpy(conn->hostname, packet->hostname, sizeof(conn->hostname));
                memcpy(conn->vendor, packet->vendor, sizeof(conn->vendor));
                pptp_reset_timer(); /* 60 seconds until keep-alive */
                log("Client connection established.");
                if (conn->callback != NULL)
                    conn->callback(conn, CONN_OPEN_DONE);
            } /* else goto pptp_conn_close; */
            break;
        }
            /* ----------- STANDARD Stop-Session MESSAGES ------------ */
        case PPTP_STOP_CTRL_CONN_RQST:
        {
            /* conn_state should be CONN_ESTABLISHED, but it could be 
             * something else */
            struct pptp_stop_ctrl_conn reply = {
                PPTP_HEADER_CTRL(PPTP_STOP_CTRL_CONN_RPLY), 
                hton8(1), hton8(PPTP_GENERAL_ERROR_NONE), 0
            };
            log("Received Stop Control Connection Request.");
            if (conn->conn_state == CONN_IDLE) break;
            if (pptp_send_ctrl_packet(conn, &reply, sizeof(reply))) {
                if (conn->callback != NULL)
                    conn->callback(conn, CONN_CLOSE_RQST);
                conn->conn_state = CONN_IDLE;
		return -1;
            }
            break;
        }
        case PPTP_STOP_CTRL_CONN_RPLY:
        {
            log("Received Stop Control Connection Reply.");
            /* conn_state should be CONN_WAIT_STOP_REPLY, but it 
             * could be something else */
            if (conn->conn_state == CONN_IDLE) break;
            conn->conn_state = CONN_IDLE;
	    return -1;
        }
            /* ----------- STANDARD Echo/Keepalive MESSAGES ------------ */
        case PPTP_ECHO_RPLY:
        {
            struct pptp_echo_rply *packet = 
                (struct pptp_echo_rply *) buffer;
            logecho( PPTP_ECHO_RPLY);
            if ((conn->ka_state == KA_OUTSTANDING) && 
                    (ntoh32(packet->identifier) == conn->ka_id)) {
                conn->ka_id++;
                conn->ka_state = KA_NONE;
                pptp_reset_timer();
            }
            break;
        }
        case PPTP_ECHO_RQST:
        {
            struct pptp_echo_rqst *packet = 
                (struct pptp_echo_rqst *) buffer;
            struct pptp_echo_rply reply = {
                PPTP_HEADER_CTRL(PPTP_ECHO_RPLY), 
                packet->identifier, /* skip hton32(ntoh32(id)) */
                hton8(1), hton8(PPTP_GENERAL_ERROR_NONE), 0
            };
            logecho( PPTP_ECHO_RQST);
            pptp_send_ctrl_packet(conn, &reply, sizeof(reply));
            pptp_reset_timer();
            break;
        }
            /* ----------- OUTGOING CALL MESSAGES ------------ */
        case PPTP_OUT_CALL_RQST:
        {
            struct pptp_out_call_rqst *packet =
                (struct pptp_out_call_rqst *)buffer;
            struct pptp_out_call_rply reply = {
                PPTP_HEADER_CTRL(PPTP_OUT_CALL_RPLY),
                0 /* callid */, packet->call_id, 1, PPTP_GENERAL_ERROR_NONE, 0,
                hton32(PPTP_CONNECT_SPEED), 
                hton16(PPTP_WINDOW), hton16(PPTP_DELAY), 0 
            };
            log("Received Outgoing Call Request.");
            /* XXX PAC: eventually this should make an outgoing call. XXX */
            reply.result_code = hton8(7); /* outgoing calls verboten */
            pptp_send_ctrl_packet(conn, &reply, sizeof(reply));
            break;
        }
        case PPTP_OUT_CALL_RPLY:
        {
            struct pptp_out_call_rply *packet =
                (struct pptp_out_call_rply *)buffer;
            PPTP_CALL * call;
            u_int16_t callid = ntoh16(packet->call_id_peer);
            log("Received Outgoing Call Reply.");
            if (!vector_search(conn->call, (int) callid, &call)) {
                log("PPTP_OUT_CALL_RPLY received for non-existant call: "
                        "peer call ID (us)  %d call ID (them) %d.",
                        callid, ntoh16(packet->call_id));
                break;
            }
            if (call->call_type != PPTP_CALL_PNS) {
                log("Ack!  How did this call_type get here?"); /* XXX? */
                break; 
            }
            if (call->state.pns != PNS_WAIT_REPLY) {
                warn("Unexpected(?) Outgoing Call Reply will be ignored.");
                break;
            }
            /* check for errors */
            if (packet->result_code != 1) {
                /* An error.  Log it verbosely. */
                log("Our outgoing call request [callid %d] has not been "
                        "accepted.", (int) callid);
                ctrlp_error(packet->result_code, packet->error_code,
                        packet->cause_code, pptp_out_call_reply_result,
                        MAX_OUT_CALL_REPLY_RESULT);
                call->state.pns = PNS_IDLE;
                if (call->callback != NULL)
                    call->callback(conn, call, CALL_OPEN_FAIL);
                pptp_call_destroy(conn, call);
            } else {
                /* connection established */
                call->state.pns = PNS_ESTABLISHED;
                call->peer_call_id = ntoh16(packet->call_id);
                call->speed        = ntoh32(packet->speed);
                pptp_reset_timer();
                /* call pptp_set_link. unless the user specified a quirk
                   and this quirk has a set_link hook, this is a noop */
                pptp_set_link(conn, call->peer_call_id);
                if (call->callback != NULL)
                    call->callback(conn, call, CALL_OPEN_DONE);
                log("Outgoing call established (call ID %u, peer's "
                        "call ID %u).\n", call->call_id, call->peer_call_id);
            }
            break;
        }
            /* ----------- INCOMING CALL MESSAGES ------------ */
            /* XXX write me XXX */
            /* ----------- CALL CONTROL MESSAGES ------------ */
        case PPTP_CALL_CLEAR_RQST:
        {
            struct pptp_call_clear_rqst *packet =
                (struct pptp_call_clear_rqst *)buffer;
            struct pptp_call_clear_ntfy reply = {
                PPTP_HEADER_CTRL(PPTP_CALL_CLEAR_NTFY), packet->call_id,
                1, PPTP_GENERAL_ERROR_NONE, 0, 0, {0}
            };
            log("Received Call Clear Request.");
            if (vector_contains(conn->call, ntoh16(packet->call_id))) {
                PPTP_CALL * call;
                vector_search(conn->call, ntoh16(packet->call_id), &call);
                if (call->callback != NULL)
                    call->callback(conn, call, CALL_CLOSE_RQST);
                pptp_send_ctrl_packet(conn, &reply, sizeof(reply));
                pptp_call_destroy(conn, call);
                log("Call closed (RQST) (call id %d)", (int) call->call_id);
            }
            break;
        }
        case PPTP_CALL_CLEAR_NTFY:
        {
            struct pptp_call_clear_ntfy *packet =
                (struct pptp_call_clear_ntfy *)buffer;
            log("Call disconnect notification received (call id %d)",
                    ntoh16(packet->call_id));
            if (vector_contains(conn->call, ntoh16(packet->call_id))) {
                PPTP_CALL * call;
                ctrlp_error(packet->result_code, packet->error_code,
                        packet->cause_code, pptp_call_disc_ntfy,
                        MAX_CALL_DISC_NTFY);
                vector_search(conn->call, ntoh16(packet->call_id), &call);
                pptp_call_destroy(conn, call);
            }
            /* XXX we could log call stats here XXX */
            /* XXX not all servers send this XXX */
            break;
        }
        case PPTP_SET_LINK_INFO:
        {
            /* I HAVE NO CLUE WHAT TO DO IF send_accm IS NOT 0! */
            /* this is really dealt with in the HDLC deencapsulation, anyway. */
            struct pptp_set_link_info *packet =
                (struct pptp_set_link_info *)buffer;
            /* log it. */
            log("PPTP_SET_LINK_INFO received from peer_callid %u",
                    (unsigned int) ntoh16(packet->call_id_peer));
            log("  send_accm is %08lX, recv_accm is %08lX",
                    (unsigned long) ntoh32(packet->send_accm),
                    (unsigned long) ntoh32(packet->recv_accm));
            if (!(ntoh32(packet->send_accm) == 0 &&
                    ntoh32(packet->recv_accm) == 0))
                warn("Non-zero Async Control Character Maps are not supported!");
            break;
        }
        default:
            log("Unrecognized Packet %d received.", 
                    (int) ntoh16(((struct pptp_header *)buffer)->ctrl_type));
            /* goto pptp_conn_close; */
            break;
    }
    return 0;
pptp_conn_close:
    warn("pptp_conn_close(%d)", (int) close_reason);
    pptp_conn_close(conn, close_reason);
    return 0;
}
コード例 #7
0
void main(void) {
  int i, j, retval;

  VECTOR *v = vector_create();
  assert(v != NULL);
  assert(vector_size(v)==0);
  for (i=0; i<=MAX; i++) {
    assert(!vector_contains(v, i));
    assert(!vector_remove(v, i));
    assert(!vector_search(v, i, (PPTP_CALL **)&j));
    retval = vector_scan(v, i, MAX*2, &j);
    assert(retval);
    assert(j==i);
  }

  for (i=1; i<=MAX; i++) {
    retval = vector_insert(v, i, (PPTP_CALL *)i);
    assert(retval);
    assert(vector_size(v)==i);
  }
  for (i=1; i<MAX; i++) {
    retval = vector_search(v, i, (PPTP_CALL **)&j);
    assert(retval);
    assert(j==i);
    retval = vector_contains(v, i);
    assert(retval);
  }
  assert(vector_size(v)==MAX);
  retval = vector_contains(v, MAX+1);
  assert(!retval);
  retval = vector_search(v, MAX+1, (PPTP_CALL **)&j);
  assert(!retval);

  retval = vector_scan(v, 0, MAX, &j);
  assert(retval);
  assert(j==0);
  retval = vector_scan(v, 1, MAX, &j);
  assert(!retval);
  retval = vector_scan(v, 1, MAX+1, &j);
  assert(retval);
  assert(j==MAX+1);
  retval = vector_scan(v, 1, MAX+MAX, &j);
  assert(retval);
  assert(j==MAX+1);

  for (i=0; i<(MAX*10); i++) {
    int k = (random() % MAX) + 1;
    assert(vector_contains(v, k));
    assert(!vector_scan(v, 1, k, &j));
    assert(!vector_scan(v, k, MAX, &j));
    retval = vector_remove(v, k);
    assert(retval);
    assert(vector_size(v)==MAX-1);
    assert(!vector_contains(v, k));
    assert(!vector_search(v, k, (PPTP_CALL **) &j));
    retval = vector_scan(v, 1, MAX, &j);
    assert(retval);
    assert(j==k);
    retval = vector_insert(v, k, (PPTP_CALL *) k);
    assert(retval);
    assert(vector_size(v)==MAX);
    assert(vector_contains(v, k));
    assert(!vector_scan(v, 1, MAX, &j));
    retval = vector_search(v, k, (PPTP_CALL **) &j);
    assert(retval);
    assert(j==k);
  }

  for (i=1; i<=MAX; i++) {
    assert(vector_size(v)==MAX-(i-1));
    vector_remove(v, i);
    assert(vector_size(v)==MAX-i);
    assert(!vector_contains(v, i));
    retval = vector_search(v, i, (PPTP_CALL **) &j);
    assert(!retval);
    retval = vector_scan(v, 1, MAX, &j);
    assert(retval);
    assert(j==1);
  }
  assert(vector_size(v)==0);
  vector_destroy(v);
}