Skip to main content

Ralsina.Me — Roberto Alsina's website

Posts about spf

Official RaSPF page

Ok, time to go a lit­tle more pub­lic with this.

Here's a page for it (click on "read more") and I will ask the open­spf guys to put it on the im­ple­men­ta­tions list (let's see how that goes).

RaSPF on its way to release

I have been able to work some more on RaSPF and the re­sults are en­cour­ag­ing.

Thanks to val­grind and test suites, I am pret­ty con­fi­dent it does­n't leak mem­o­ry, or at least, that it does­n't leak ex­cept on very rare cas­es.

I think I found a neat way to sim­pli­fy mem­o­ry man­age­men­t, though, and that's what I want­ed to men­tion.

This is prob­a­bly triv­ial for ev­ery­one read­ing, but I am a lim­it­ed C pro­gram­mer, so when­ev­er some­thing works un­ex­pect­ed­ly right, I am hap­py ;-)

One prob­lem with C mem­o­ry man­age­ment is that if you have many ex­it points for your func­tion­s, re­leas­ing ev­ery­thing you al­lo­cate is rather an­noy­ing, since you may have to do it in sev­er­al dif­fer­ent lo­ca­tion­s.

I com­pound­ed this prob­lem be­cause I am us­ing ex­cep­tions (yeah, C does­n't have them. I used this).

Now not on­ly do I have my re­turns but al­so my throws and what­ev­er un­caught throw some­thing I called has!

Hel­l, right?

Nope: what ex­cep­tions com­pli­cat­ed, ex­cep­tions fixed. Look at this func­tion:

bstring spf_query_get_explanation(spf_query *q, bstring spec)
{
    bstring txt=0;
    struct bstrList *l=0;
    bstring expanded=0;
    bstring result=0;
    struct tagbstring s=bsStatic("");

    try
    {
        // Expand an explanation
        if (spec && spec->slen)
        {
            expanded=spf_query_expand(q,spec,1);
            l=spf_query_dns_txt(q,expanded);

            if (l)
            {
                txt=bjoin(l,&s);
            }
            else
            {
                txt=bfromcstr("");
            }
            result=spf_query_expand(q,txt,0);
            throw(EXC_OK,0);
        }
        else
        {
            result=bfromcstr("explanation: Required option is missing");
            throw(EXC_OK,0);
        }
    }
    except
    {
        if(expanded) bdestroy(expanded);
        if(txt) bdestroy(txt);
        if(l) bstrListDestroy(l);
        on (EXC_OK)
        {
            return result;
        }
        if(result) bdestroy(result);
        throw(EXCEPTION.type,EXCEPTION.param1);
    }
}

It does­n't mat­ter if spf_­query_­ex­pand or spf_­query_dns_txt throw an ex­cep­tion, this will not leak.

Nice, I think :-)

SPF test suite on RASPF

Here are the re­sults as of right now:

  • Give the ex­pec­t­ed re­­sult­s: 82 tests

  • Give the wrong re­­sult: 48 tests

  • Give a cor­rect but not pre­­ferred re­­sult (most­­ly be­­cause of SPF records and IPv6): 6 tests

  • Fail (crash): 9 tests

So, de­pend­ing on how you look at it, RASPF pass­es be­tween 61% and 56% of the test­s.

Not bad so far :-)

Up­date: As of 20:52 ART, it's 105/0/35/5 and 72-76%. The bad news is that that was all the low hang­ing fruit, and now it gets much hard­er.

My SPF lib improving

It now can do a bunch of things like ex­pand­ing macros and (in some cas­es) val­i­dat­ing mech­a­nism­s.

I am mak­ing very heavy use of unit test­ing, be­cause it's a pret­ty com­plex piece and each func­tion needs to do ex­act­ly the right thing or ev­ery­thing else fails (it's pret­ty hard to fig­ure out where it will fail ;-)

You can check the 947 LOC thing at http://­code.­google.­com/p/raspf (the Code tab).

If you do check it, jeep in mind the fol­low­ing:

  • It us­es a few lib­s, and they are in­­­clud­ed in the source code for sim­­plic­i­­ty.

  • I do some­­times com­mit code that does­n't com­pile

  • I do some­­times com­mit code that fails tests

  • You need cmake

  • I am not giv­ing a damn about mem­o­ry man­age­­ment right now, so don't both­­er wor­ry­ing about leak­s: ev­ery­thing leaks in this code. I want to make it func­­tion­al first, then I can plug it one func­­tion at a time (sim­­ply by run­n­ing the unit test­ing code with a mem­o­ry check­­er).

En­joy (although it's not pre­cise­ly en­joy­able code right now ;-)


Contents © 2000-2023 Roberto Alsina