2013년 9월 25일 수요일

무비캣(moviecat) 소액결제 사기 취소하기

* 소액결제 취소방법은 밑에 부분에 설명되있습니다.

추석연휴 끝나는 주말 저녁에 "아빠어디가"를 보기위해 토렌트를 검색하다가
이상한 토렌트사이트에 낚여서 소액결제 사기를 당하고 말았다.

그 토렌트사이트는 가입 절차에서 휴대폰 인증을 요구하는데
휴대폰 인증번호를 받아서 입력하고 확인을 누르는 순간
무비켓(moviecat)이라는 전혀 엉뚱한 사이트에 가입 되면서
소액결제가 되버린다.

이런 페이지에
가입하면!!!









이런 결제완료 문제가 온다!!. 망할

















그리고 이 무비캣 사이트로
가입이되면서 이동한다.. -_-;;;
정말 욕나온다..!!!









그리고 다날페이에 들어가서
확인해보면 소액결제 내역을
확인할수 있다.

다날.. 이놈들도 정말 어처구니없다.. 
이런 그지 같은 사이트는 알아서
필터링 해야지..









일단 통신사 114로 전화해서 해결할수도 있으나... 이것도 결국 통신사에서
무비캣에 전화후 피해자한테 전화를 먼저 걸어 취소하도록 압력을 가하는 정도다.
만약 무비캣이 게으르거나.. 배째면 대책이없다.

그 다음 단계로 여러가지 중재하는 단체 및 사이트를 이용할수 있으나..
구구절절 작성하기가 상당히 귀찮다.

그럼 어떤방법이 있냐면..
정말 이상하게도 이놈의 무비캣사이트는 무슨 의도로 만들어졌는지는 모르겠지만
소액결제 취소하는 방법도 매우 쉽게 하도록 방법을 제공하고 있다.. ㅡ,.ㅡ

사기쳐서 소액결제 유도하고.. 소액결체를 취소할수 있는 방법도 마련하다니..
이해가 안간다 -_-??? 그냥 모르는 몇명만 탈없이 낚아보자 그건가 ;;;;

일단 무비캣사이트 하단에 보이는 "고객센터 : 1644-8965" 로 전화를 하자!!
그럼 "1번 상담원 연결"을 안내하는데 어짜피 안받으니까 무시하고!! 기다리면
"2번 ARS취소"를 안내해 준다.


여기서 2번을 누르고 알려주는 절차대로 누르기만 하면 바로 소액결제가 취소 된다.


요약
1. 무비캣 사이트 하단 전화번호로 전화를 한다. (1644-8965)
2. "1번 상담원연결"은 무시하고 "2번  ARS취소"를 선택한다.
3. 안내 메시지에 따라서 취소한다.
4. 다날페이에서 소액결제 내역이 사라진것을 최종확인!! ^^;

정상적으로 취소 문자도 온다~^^




2013년 8월 8일 목요일

fiber 예제

쓰레드는 OS가 실행 단위들을 스케쥴링을 해주는 것이며 fiber는 user level에서 특정 API르 이용하여 실행 단위를 user level에서 직접 스케쥴링을 하는 기법이다. 사용용도를 간단히 설명하면 비동기식  I/O를 사용하면서 짬짬이 다른 문맥을 수행하거나 단일 프로세스 구조에서 thread없이 단순히 문맥만 분리 시킴으로 queue구조를 운영할수도 있다.

아래 예제에서 사용된 API들은 glibc에서 기본으로 제공되는 함수이며 swapcontext()의 내부 로직은 user level에서 직접 프로세스 실행에 대한 레지스터값을 저장하고 복원하는 방법을 상요하여 문맥을 전환 하고 있다.

그러나 문맥전환이 일어하는 과정에서 추가적으로 signal 정보를 저장, 복원 하는 작업도 발생하게 되는데 이로 인하여 system call overhead가 걸려서 문맥전환이 생각보다 느리게 수행되는 단점도 존재한다.

막약 signal을 다룰필요가 없는 프로그램을 작성한다면 glibc의 swapcontext() 함수 내부에서 signal 정보를 저장, 복원 하는 부분만 삭제하게 될 경우 커널의 스케쥴링으로는 도저히 볼수없는 정말 환상적인 문맥전환 성능을 만날수있다.

#include <stdio.h>
#include <stdint.h>
#include <signal.h>
#include <ucontext.h>

static ucontext_t main_ctx;

static ucontext_t test_ctxA;
static ucontext_t test_ctxB;

static uint64_t cnt = 0;

static uint64_t cnt_old = 0;

static void fiber_funcA(void)

{
    for (;;) {
        ++cnt;
        // Conext B 로 문맥전환
        swapcontext(&test_ctxA, &test_ctxB);
    }
}

static void fiber_funcB(void)

{
    for (;;) {
        ++cnt;
        // Conext A 로 문맥전환
        swapcontext(&test_ctxB, &test_ctxA);
    }
}

static void sighandler(int signal)

{
    printf("%lu \n", cnt - cnt_old);
    cnt_old = cnt;
    alarm(1);
}

int main(void)

{
    char stackA[2048];
    char stackB[2048];

    // 문맥전환 횟수 모니터링용 헨들러

    signal(SIGALRM, sighandler);
    alarm(1);

    // Conext A fiber 생성

    if (getcontext(&test_ctxA) < 0)
    {
        fprintf(stderr, "ERROR!!\n");
        return 1;
    }
    test_ctxA.uc_stack.ss_sp = stackA;
    test_ctxA.uc_stack.ss_size = sizeof(stackA);
    test_ctxA.uc_link = &main_ctx;
    makecontext(&test_ctxA, (void (*)(void))fiber_funcA, 0);

    // Conext B fiber 생성

    if (getcontext(&test_ctxB) < 0)
    {
        fprintf(stderr, "ERROR!!\n");
        return 1;
    }
    test_ctxB.uc_stack.ss_sp = stackB;
    test_ctxB.uc_stack.ss_size = sizeof(stackB);
    test_ctxB.uc_link = &main_ctx;
    makecontext(&test_ctxB, (void (*)(void))fiber_funcB, 0);

    // Conext Main 에서 Conext A로 문맥 전환

    swapcontext(&main_ctx, &test_ctxA);

    return 0;

}

2013년 7월 31일 수요일

Linux memory overcommit 정책

리눅스에서 overcommit의 정책은 총 3가지가 존재하며 overcommit 정책은 "echo 2 > /proc/sys/vm/overcommit_memory" 와 같은 명령을 사용하여 변경이 가능하다.

각 정책에서 수행되는 overcommit 동작 방식은 아래와 같다.

  • OVERCOMMIT_GUESS (0)
Heuristic으로 계산된 크기만큼 overcommit을 허용하는 정책으로 Linux의 기본정책이다. 여기서 Heuristic이라는 말이 참 애매한데.. kernel에서 수행되는 로직을 살펴 보면 새로운 VM할당이 요청되면 새로 추가 요청된 사이즈와 "file page + SLAB reclaimable + (free pages - reserve pages)"에 의해서 계산된 실제 가용한 메모리 공간을 비교하여 요청된 사이즈가 더 작을 경우 vm할당을 성공시키고 있다.
예를 들어 간단히 설명하자면, 시스템에 1G의 가용한 메모리가 있는 상태에서 malloc(1G이상)은 실패하지만 malloc(1G이하)는 계속해서 성공시켜 준다.

  • OVERCOMMIT_ALWAYS (1)
시스템의 메모리 상태와 상관없이 무조건 overcommit을 성공시켜준다. malloc()은 항상 성공

  • OVERCOMMIT_NEVER  (2)
시스템이 가지고 있는 물리메모리 총량에 hugepage 사용분을 제거하고 "/proc/sys/vm/overcommit_ratio"값을 반영한 다음 swap partition크기를 더해서 계산된 Commit limit 값을 기준으로 VM할당을 제한하는정책이다.
만약 16G 시스템에서 overcommit_ratio가 50이고 hugepage를 사용하지 않고 swap partition이 없을 경우 Commit limit은 8G가 된다. 이런 경우 이 시스템은 8G이상의 메모리를 할당할수 없다. 남은 8G의 메모리는 낭비된다.

2013년 2월 18일 월요일

Interface Name to PCI bus information

Interface Name 을 이용해서 PCI bus를 조회해야하는 API가 필요해서 popen()을 통해서 ethtool을 실행하여 간단하게 만들어 봤다.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

char * ifname2pcibus(const char *ifname)

{
    int i;
    size_t rs;
    FILE *fp = NULL;
    char buf1[1024];
    char buf2[1024];
    char full_bus_name[1024];

    // Run command

    sprintf(buf1,"ethtool -i %s | grep \"bus-info:\" | sed -e \"s/bus-info: //\"", ifname);
    fp = popen(buf1, "r");
    if(!fp)
    {
        fprintf(stderr,"popen error\n");
        return NULL;
    }

    // Read PCI bus information

    rs = fread((void*)buf2, sizeof(char), 1024-1, fp);
    if(!rs)
    {
        pclose(fp);
        fprintf(stderr,"popen read error\n");
        return NULL;
    }
    pclose(fp);
    buf2[rs] = '\0';

    // Remove Newline character

    for ( i = 0 ; i < rs ; i++ )
    {
        if ( isspace(buf2[i]) )
            buf2[i] = '\0';
    }

    return strdup(buf2);

}

int main(void)

{
    char * pcibus;
    pcibus = ifname2pcibus("eth0");
    if(pcibus)
    {
        printf("eth0 : %s \n", pcibus);
        free(pcibus);
    }

    return 0;

}

위 상태로 사용하는 것도 문제 될 만한 것은 없지만 매우 무거운 프로그램 내부에서 popen()을 하게 될 경우 내부적으로 수행되는 fork()에 의한 부담이 커지는 관계로 ioctl()을 이용한 버전을 다시 만듦.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <net/if.h>
#include <sys/socket.h>
#include <linux/ethtool.h>
#include <linux/sockios.h>

char *ifname2pcibus(const char *ifname)

{
    int fd;
    struct ifreq ifr;
    struct ethtool_drvinfo drvinfo;

    // Open socket

    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(fd<0)
        return NULL;

    // Make Request structure

    memset(&ifr, 0x00, sizeof(ifr));
    strcpy(ifr.ifr_name, ifname);
    drvinfo.cmd = ETHTOOL_GDRVINFO;
    ifr.ifr_data = (void*)&drvinfo;

    // Get Driver information

    ioctl(fd, SIOCETHTOOL, &ifr);

    close(fd);

    return strdup(drvinfo.bus_info);
}

int main(void)

{
    char * pcibus;
    pcibus = ifname2pcibus("eth0");
    if(pcibus)
    {
        printf("eth0 : %s \n", pcibus);
        free(pcibus);
    }

    return 0;

}