Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

apn_connect() block forever #9

Open
hex2tan opened this issue Aug 11, 2015 · 3 comments
Open

apn_connect() block forever #9

hex2tan opened this issue Aug 11, 2015 · 3 comments

Comments

@hex2tan
Copy link
Contributor

hex2tan commented Aug 11, 2015

Hi, this is my code, what just use the sample http://libcapn.org/doc/html/send_push_8c-example.html code, a little different is use the apn_payload_add_custom_property_string() in some codition.
int32_t PushToApple(std::string& strIosToken, std::string& strMsg,int32_t nBadge,const char* pstrExt)
{
apn_payload_ctx_ref payload_ctx = NULL;
apn_ctx_ref ctx = NULL;
apn_error_ref error = NULL;
const char *cert_path = "apns-pro-cert.pem";
const char *key_path = "apns-pro-key-noenc.pem";
const char *push_message = strMsg.c_str();
const char *token = strIosToken.c_str();
time_t time_now = 0;
if(apn_init(&ctx, cert_path, key_path, NULL, &error) == APN_ERROR)
{
printf("%s: %d\n", apn_error_message(error), APN_ERR_CODE_WITHOUT_CLASS(apn_error_code(error)));
apn_error_free(&error);
return fail;
}
apn_set_mode(ctx, APN_MODE_SANDBOX, NULL);
apn_add_token(ctx, token, NULL);

if(apn_payload_init(&payload_ctx, &error) == APN_ERROR)
{
    printf("%s: %d\n", apn_error_message(error), APN_ERR_CODE_WITHOUT_CLASS(apn_error_code(error)));
    apn_free(&ctx);
    apn_error_free(&error);
    return fail;
}

time(&time_now);
apn_payload_set_badge(payload_ctx, nBadge, NULL);
apn_payload_set_body(payload_ctx, push_message, NULL);
apn_payload_set_expiry(payload_ctx, time_now + 3600, NULL);
apn_payload_set_sound(payload_ctx, "default",  NULL);
apn_payload_add_custom_property_integer(payload_ctx, "int_property", 20, NULL);
if(NULL != pstrExt)
    apn_payload_add_custom_property_string(payload_ctx,"ext",pstrExt, NULL);

ctx->mode = APN_MODE_PRODUCTION;
if(apn_connect(ctx, &error) == APN_ERROR)
{
    printf("Could not connected to Apple Push Notification Servece: %s (%d)\n", apn_error_message(error), APN_ERR_CODE_WITHOUT_CLASS(apn_error_code(error)));
    apn_payload_free(&payload_ctx);
    apn_free(&ctx);
    apn_error_free(&error);
    return fail;
}

if(apn_send(ctx, payload_ctx, &error) == APN_ERROR)
{
    printf("Could not sent push: %s (%d)\n", apn_error_message(error),  APN_ERR_CODE_WITHOUT_CLASS(apn_error_code(error)));
    if(APN_ERR_CODE_WITHOUT_CLASS(apn_error_code(error)) == APN_ERR_TOKEN_INVALID)
    {
        printf("Invalid token: %s\n", apn_error_invalid_token(error));
    }
    apn_close(ctx);
    apn_payload_free(&payload_ctx);
    apn_free(&ctx);
    apn_error_free(&error);
    return fail;
}

apn_close(ctx);
apn_payload_free(&payload_ctx);
apn_free(&ctx);
return success;

}
The code work fine most of time.But sometimes, it does not, the application was blocked by apn_connect() accidentally, once a day recently.
Then I used the strace -p pid, just give a message blow:
read(39,
no more message.
And with the gdb attach the application process id, the message blow:
apn_gdb_bt_info
it looks like block at __read_nocancel().
So, after googling, I found the issues on stackoverflow:
http://stackoverflow.com/questions/11835203/openssl-ssl-connect-blocks-forever-how-to-set-timeout
and I view the libcapn source code, the __apn_connect() doesn't use the SSL_CTX_set_timeout() or SSL_SESSION_set_timeout(), of course it may have no effect just like that guy said.
Following, I will try to add SSL_CTX_set_timeout() or SSL_SESSION_set_timeout() to the __apn_connect() fuction and test it works or not.

I suggest give a fuction whic like apn_connect_timeout so that it can be setted the timeout.
THX.

@dungwinve
Copy link

I met this problem too, how can you resolve this, can you share the method?

@adobkin
Copy link
Owner

adobkin commented Aug 18, 2015

I'll take care of the issue immediately as soon as possible. May be @hex2tan can check use SSL_CTX_set_timeout() before me

@hex2tan
Copy link
Contributor Author

hex2tan commented Aug 31, 2015

@dungwinve I don't have time to try SSL_CTX_set_timeout() or SSL_SESSION_set_timeout() yet. I have just used the SIGALRM signal to interrupt the block, and it work well for two weeks now.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants